20

Qual è la differenza principale tra due dei seguenti approcci:Differenza tra ThreadPool.QueueUserWorkItem e Parallel.ForEach?

ThreadPool.QueueUserWorkItem

Clients objClient = new Clients(); 
    List<Clients> objClientList = Clients.GetClientList(); 

    foreach (var list in objClientList) 
    { 
     ThreadPool.QueueUserWorkItem(new WaitCallback(SendFilesToClient), list); 
    } 

System.Threading.Tasks.Parallel PerOgni

Clients objClient = new Clients(); 
    List<Clients> objClientList = Clients.GetClientList(); 

    Parallel.ForEach<Clients>(objClientList, list => 
    { 
     SendFilesToClient(list); 
    }); 

Sono nuovo di multi-threading e vogliono sapere cosa succederà in ogni caso (in termini di processo di esecuzione) qual è il livello di multi- threading per ogni approccio? Aiutami a visualizzare entrambi i processi.

SendFilesToClient: ottiene i dati dal database, converte in Excel e invia il file Excel per rispettivo client.

Grazie!

risposta

21

La differenza principale è funzionale. Parallel.ForEach verrà bloccato (in base alla progettazione), quindi non verrà restituito finché tutti gli oggetti non saranno stati elaborati. Il lavoro del thread di thread di accodamento di accodamento foreach spinge il lavoro sui thread in background e non il blocco.

Inoltre, la versione Parallel.ForEach avrà altri importanti vantaggi: le eccezioni non gestite verranno reindirizzate al sito di chiamata qui, invece che non gestite in un thread ThreadPool.

In generale, Parallel.ForEach sarà più efficiente. Entrambe le opzioni utilizzano ThreadPool, ma il Parallel.ForEach esegue il partizionamento intelligente per impedire la sovrascrittura e per ridurre la quantità di sovraccarico richiesta dallo scheduler. Le singole attività (che verranno mappate ai thread ThreadPool) vengono riutilizzate ed effettivamente "raggruppate" per ridurre l'overhead, specialmente se SendFilesToClient è un'operazione veloce (che, in questo caso, non sarà vera).

Si noti che è anche possibile, come una terza opzione, utilizzare PLINQ:

objClientList.AsParallel().ForAll(SendFilesToClient); 

Questo sarà molto simile al metodo Parallel.ForEach in termini di prestazioni e funzionalità.

+0

Grazie per la spiegazione dettagliata @Reed. Due domande: 1) Perché il blocco è importante (sarebbe bello se tu possa rispondere in relazione al mio codice)? 2) Estendendo ulteriormente la domanda principale, c'è qualche ulteriore vantaggio nell'usare PLINQ su Parallel.ForEach? – Learner

+0

@Mihir 1) il blocco è solo diverso. Il thread in esecuzione attenderà che Parallel.ForEach finisca prima di eseguire la riga successiva del codice, ma il codice foreach/TP.QUWI non attenderà. 2) Nessun vantaggio, diverso dal codice potenzialmente più semplice da capire –

+0

Grande, grazie ancora per la spiegazione! – Learner