Domanda

Ho un abbastanza processo Metodo intensivo che prende un dato di raccolta, copia le voci (la classe di oggetto è la sua copia () il metodo correttamente definito), popola la voce con i dati e restituisce la raccolta popolata alla proprietà raccolta della classe

//populate Collection containing 40 items
MyClass.CollectionOfItems = GetPopulatedCollection(MyClass.CollectionOfItems );

Questo metodo viene chiamato in due modi:. Su richiesta e tramite evento 'trascorso' di un oggetto System.Timers.Timer

Ora 40 articoli della collezione prendono pochissimo tempo a tutti. Sia in fase di popolate 'ad hoc' per esempio un Button_Click o popolato da l'oggetto Timer.

Ora, quando ho aumentare la dimensione della collezione (un altro oggetto MyClass che ha 1000 articoli), il processo richiede più prevedibile, ma intorno 6sec in totale. Va bene, non abbiamo avuto problemi. Essere chiamato inizializzazione (form_load) o essere chiamato ad hoc (Button_Click) rimane intorno 6sec.

//populate Collection containing 1000 items
MyClass.CollectionOfItems = GetPopulatedCollection(MyClass.CollectionOfItems );

Ma, lo stesso metodo (come nella linea esatta di codice) viene chiamato dall'oggetto System.Timers.Timer. E intercorso impiega circa 60 secondi (altre piste 56sec unclide, 1min 2Sec, 1min 10 sec ... si ottiene l'idea). Dieci volte più a lungo per lo stesso processo!

So che l'oggetto System.Timers.Timer viene eseguito nel thread-piscina. Potrebbe essere questa la ragione? È il filo-piscina data la priorità più bassa o è la cosa messa in coda prendendo il tempo?

In breve, ciò sarebbe un approccio migliore per questo? Utilizzando lo System.Windows.Forms.Timer per eseguire nello stesso thread UI?

Grazie!

Ok, alcune informazioni aggiuntive:

Il funzionamento del timer avviene entro un DLL essere chiamato dalla UI. Il principale 'gestore' classe stessa ha una collezione di oggetti di timer tutto sottoscrive lo stesso gestore di eventi. L'inizializzazione classe del gestore funziona un po 'come questo:

UpdateIntervalTimer tmr = new UpdateIntervalTimer(indexPosition);
tmr.Interval = MyClass.UpdateInterval * 60000; //Time in minutes
tmr.Elapsed += new System.Timers.ElapsedEventHandler(tmr_Elapsed);
this.listIntervalTimers.Add(tmr);

In realtà ho ereditato la classe Timer per dare un 'index' (I eventArgs pure). In questo modo all'interno di un gestore di eventi (tmr_Elapsed) posso identificare quali MyClass oggetto il timer è e agire.

La classe gestore è già in esecuzione in un thread a sé stante e spara un evento personalizzato per dare comprensione per le sue operazioni. L'evento viene gestito nell'interfaccia utente (cross-filettatura accesso dei controlli UI e quant'altro) e visualizzate con il tempo recievedthe evento viene gestito. Questo è vero sia per la 'inizializzazione' e 'ad hoc' chiamate (non c'è nessun problema in questi casi).

L'evento reale trascorso appare come segue:

private void tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
            UpdateIntervalTimer tmr;
            tmr = (UpdateIntervalTimer)sender;

            MyClass c = listOfClasses[tmr.IndexPosition];

            observerEventArguments = new MyHandlerEventArgs("Timer is updating data for " + MyClass.ID);
            MessagePosted(this, observerEventArguments);

            try
            {
                //preparation related code


                MyClass.CollectionOfItems = GetPopulatedCollection(MyClass.CollectionOfItems);


                observerEventArguments = new ProfileObserverEventArgs(MyClass.ID + ": Data successfully updated");
                MessagePosted(this, observerEventArguments);
            }
            catch (Exception exUpdateData)
            {
                observerEventArguments = new MyHandlerEventArgs("There was an error updating the data for '" + MyClass.ID + "': " + exUpdateData.Message);
                MessagePosted(this, observerEventArguments);
            }
        }
È stato utile?

Soluzione

Bene, il thread UI è probabilità di avere una priorità più alta - dopo tutto, è pensata per mantenere l'interfaccia utente sensibile. Tuttavia, ci sono altre cose che potrebbero essere in corso. Il vostro metodo di accesso l'interfaccia utente in modo thread-safe? Se è così, ovviamente, sta andando essere più veloce quando non ha bisogno di Marshall tra i thread.

Si potrebbe provare a incrementare la priorità del thread pool di thread per vedere se questo migliora le prestazioni - ma a parte questo, avremo bisogno di ulteriori informazioni

.

I non sarebbe consiglio di fare questo sul thread UI - appesa l'interfaccia utente per 6 secondi non fa per una bella esperienza utente: (

Altri suggerimenti

è l'intervallo che intercorre, mentre si sta ancora facendo il lavoro nel timer, inducendolo a fare lo stesso lavoro più volte? Questo è l'unico motivo che posso pensare che il timer interfaccia utente funziona più veloce rispetto al System.Timers.Timer / System.Threading.Timer, dal momento che il timer di interfaccia utente è a thread singolo e non può terminare di nuovo finché non è finito, mentre gli altri possono.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top