c# multithreading windows-services parallel.foreach queueuserworkitem

c# - ¿Diferencia entre ThreadPool.QueueUserWorkItem y Parallel.ForEach?



multithreading windows-services (1)

¿Cuál es la principal diferencia entre dos de los siguientes enfoques:

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 ForEach

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

Soy nuevo en los subprocesos múltiples y quiero saber qué sucederá en cada caso (en términos de proceso de ejecución) ¿cuál es el nivel de subprocesos múltiples para cada enfoque? Ayúdame a visualizar ambos procesos.

SendFilesToClient: Obtiene datos de la base de datos, los convierte a Excel y envía el archivo de Excel al cliente correspondiente.

¡Gracias!


La principal diferencia es funcional. Parallel.ForEach bloqueará (por diseño), por lo que no se devolverá hasta que se hayan procesado todos los objetos. El trabajo de subproceso de subprocesos de colas de foreach cola colocará el trabajo en subprocesos de fondo y no se bloqueará.

Además, la versión Parallel.ForEach tendrá otras ventajas importantes: las excepciones no manejadas se reenviarán al sitio de llamadas aquí, en lugar de dejarlas sin manejar en un subproceso de ThreadPool.

En general, Parallel.ForEach será más eficiente. Ambas opciones utilizan ThreadPool, pero Parallel.ForEach realiza una partición inteligente para evitar el subproceso y para reducir la sobrecarga requerida por el programador. Las tareas individuales (que se asignarán a los subprocesos de ThreadPool) se reutilizan y se "agrupan" de manera efectiva para reducir los gastos generales, especialmente si SendFilesToClient es una operación rápida (que, en este caso, no será cierta).

Tenga en cuenta que también puede, como una tercera opción, usar PLINQ:

objClientList.AsParallel().ForAll(SendFilesToClient);

Esto será muy similar al método Parallel.ForEach en términos de rendimiento y funcionalidad.