Per le massime prestazioni con unità in esecuzione simultanea, scrivi il tuo pool di thread, in cui un pool di oggetti Thread viene creato all'avvio e vai al blocco (precedentemente sospeso), in attesa dell'esecuzione di un contesto (un oggetto con un'interfaccia standard implementata da il tuo codice).
Così tanti articoli su Task vs. Threads vs. .NET ThreadPool non riescono a darti davvero ciò di cui hai bisogno per prendere una decisione in merito alle prestazioni. Ma quando li confronti, i thread vincono e soprattutto un pool di thread. Sono distribuiti al meglio tra le CPU e si avviano più velocemente.
Ciò che dovrebbe essere discusso è il fatto che l'unità di esecuzione principale di Windows (incluso Windows 10) è un thread e l'overhead di commutazione del contesto del sistema operativo è generalmente trascurabile. In poche parole, non sono stato in grado di trovare prove convincenti di molti di questi articoli, sia che l'articolo rivendichi prestazioni più elevate salvando il cambio di contesto o un migliore utilizzo della CPU.
Ora per un po 'di realismo:
La maggior parte di noi non avrà bisogno che la nostra applicazione sia deterministica, e la maggior parte di noi non ha uno sfondo duro con i thread, che ad esempio spesso viene con lo sviluppo di un sistema operativo. Quello che ho scritto sopra non è per un principiante.
Quindi ciò che può essere più importante è discutere di ciò che è facile da programmare.
Se crei il tuo pool di thread, avrai un po 'di scrittura da fare in quanto dovrai preoccuparti del monitoraggio dello stato di esecuzione, di come simulare la sospensione e il ripristino e di come annullare l'esecuzione, anche in un'applicazione spegnimento. Potresti anche doverti preoccupare se vuoi far crescere in modo dinamico il tuo pool e anche quali limiti di capacità avrà il tuo pool. Posso scrivere un tale framework in un'ora, ma è perché l'ho fatto così tante volte.
Forse il modo più semplice per scrivere un'unità di esecuzione è usare un'attività. Il bello di un compito è che puoi crearne uno e dargli il via in linea nel tuo codice (anche se la cautela può essere giustificata). È possibile passare un token di annullamento da gestire quando si desidera annullare l'attività. Inoltre, utilizza l'approccio promettente per concatenare gli eventi e puoi restituire un tipo specifico di valore. Inoltre, con asincrono e attendi, esistono più opzioni e il tuo codice sarà più portabile.
In sostanza, è importante comprendere i pro ei contro con Task vs. Threads vs. .NET ThreadPool. Se ho bisogno di prestazioni elevate, userò i thread e preferisco usare il mio pool.
Un modo semplice per confrontare è l'avvio di 512 thread, 512 attività e 512 thread ThreadPool. All'inizio troverai un ritardo con i thread (quindi, perché scrivere un pool di thread), ma tutti i 512 thread verranno eseguiti in pochi secondi mentre le attività e i thread .NET ThreadPool impiegano fino a pochi minuti per iniziare.
Di seguito sono riportati i risultati di tale test (i5 quad core con 16 GB di RAM), che dà ogni 30 secondi per l'esecuzione. Il codice eseguito esegue I / O di file semplici su un'unità SSD.
Risultati del test