2013-06-09 15 views
5

Mi piacerebbe sapere cosa usare per le attività che richiedono un sacco di prestazioni. Backgroundworker, Thread o ThreadPool?Thread/threadpool o backgroundworker

Finora ho lavorato con Thread, ma ho bisogno di migliorare la velocità delle mie applicazioni.

+5

Dipende da come non usarli. – I4V

risposta

13

BackgroundWorker è la stessa cosa di un thread di thread. Lo aggiunge la possibilità di eseguire eventi sul thread dell'interfaccia utente. Molto utile per mostrare i progressi e per aggiornare l'interfaccia utente con il risultato. Quindi il suo uso tipico è quello di impedire che l'interfaccia utente si congeli quando è necessario lavorare. Le prestazioni non sono il primo obiettivo, l'esecuzione del codice in modo asincrono è. Questo modello è anche abilmente esteso nelle versioni .NET successive dalla classe Task <> e dalle parole chiave async/await.

I thread del pool di thread sono utili per evitare di consumare risorse. Un thread è un costoso oggetto del sistema operativo ed è possibile creare un numero molto limitato di essi. Un thread accetta 5 handle di sistema operativo e un megabyte di spazio di indirizzi di memoria virtuale. Nessun metodo Dispose() per rilasciare queste maniglie in anticipo. Il pool di thread esiste principalmente per riutilizzare i thread e assicurarsi che non siano attivi troppi thread. È importante utilizzare un thread pool di thread solo quando il lavoro è limitato, idealmente non impiegando più di mezzo secondo. E non bloccare spesso. È quindi più adatto per brevi raffiche di lavoro, non per le situazioni in cui le prestazioni sono importanti. La gestione del completamento I/O è un compito ideale per un thread TP.

Sì, è possibile utilizzare anche i thread per migliorare le prestazioni di un programma. Lo farebbe utilizzando Thread o un'attività <> che utilizza TaskContinuationOptions.LongRunning. Ci sono alcuni requisiti difficili da ottenere in realtà un miglioramento delle prestazioni, sono piuttosto rigide:

  • È necessario più di un thread. In un caso ideale, due thread possono dimezzare il tempo necessario per ottenere un lavoro. E meno, più fili usi. Avvicinarsi a quell'ideale è tuttavia difficile, non scala in modo infinito. Google "legge di Amdahl" per informazioni.
  • È necessaria una macchina con un processore con più core. Facile da ottenere in questi giorni. Il numero di thread creati non deve superare il numero di core disponibili. L'utilizzo di più sarà di solito inferiore prestazioni.
  • È necessario il tipo di lavoro con limiti di elaborazione, in cui il motore di esecuzione del processore è la risorsa vincolata. Questo è abbastanza comune, ma certamente non slamdunk. Molti lavori sono effettivamente limitati dal throughput I/O, come la lettura da un file o una query di dbase. Oppure sono limitati dalla velocità con cui il processore può leggere i dati dalla RAM. Tali lavori non traggono vantaggio dai thread, avrete a disposizione più motori di esecuzione ma avrete ancora un solo disco e un bus di memoria.
  • È necessario un algoritmo in grado di distribuire il lavoro su più thread senza quasi alcuna necessità di sincronizzazione. Di solito questo è il problema difficile da risolvere, molti algoritmi sono di natura molto sequenziale e non sono facilmente parallelizzabili.
  • Avrai bisogno di tempo e pazienza per rendere il codice stabile e performante. La scrittura del codice filettato è rigido e una corsa al thread che causa l'arresto anomalo del programma una volta al mese o produce un risultato non valido occasionalmente può rappresentare un notevole spreco di tempo.
+0

ottima risposta! penso di avere quello di cui ho bisogno. come posso chiudere questa domanda? (Sono nuovo in questo). – user2468035

+0

@user - Basta contrassegnare la risposta. Fai clic sul segno di spunta a sinistra del post che ha risposto alla tua domanda. –

+0

Si dice di non utilizzare un oggetto BackgroundWorker per attività a esecuzione prolungata (e si usa invece 'Thread' o' Task'). Questo perché è più lento rispetto a Thread/Task, o è legato alla memoria, o perché imperversa nel sistema, o si tratta di un altro problema? Assumiamo un problema imbarazzante-parallelo con circa 4-20 core/thread (con i core fisici da abbinare) e dove il problema potrebbe richiedere alcuni minuti per risolverlo. –

0

Il framework per l'avvio di attività a uso intensivo della CPU nei thread è irrilevante per il problema, a meno che non si disponga di attività secondarie troppo piccole.

È necessario dividere il lavoro in attività secondarie che possono essere eseguite in parallelo quando si dispone di più di una CPU.

+0

grazie, questa velocità effettivamente aumentata. sta svolgendo più compiti contemporaneamente, migliorando le mie prestazioni. grazie ancora – user2468035

0

Questa scelta non ha molta importanza. BackgroundWorker è un thread ThreadPool quindi non fa differenza comunque. Tuttavia, puoi provare a ottimizzare il numero di thread con ThreadPool.SetMaxThreads.

E si consiglia di utilizzare la classe System.Threading.Task che potrebbe aiutare a ottimizzare l'esecuzione parallela.

+0

Grazie mille, ho intenzione di provare subito – user2468035