c# - net - parallel foreach try catch
¿Por qué Parallel.ForEach no ejecuta múltiples hilos? (6)
¿Por casualidad tienes un solo procesador? TPL puede limitar el número de subprocesos a uno en este caso. Lo mismo puede pasar si la colección es muy pequeña. Intenta una colección más grande. Vea esta respuesta para obtener más detalles sobre cómo se determina el grado de paralelismo.
Hoy intenté hacer alguna optimización para foreach
, que funciona en XDocument
.
Antes de la optimización:
foreach (XElement elem in xDoc.Descendants("APSEvent").ToList())
{
//some operations
}
Después de la optimización:
Parallel.ForEach(xDoc.Descendants("APSEvent").ToList(), elem =>
{
//same operations
});
Vi que .NET en Parallel.ForEach(...)
abrió SÓLO un hilo! Como resultado, el tiempo de Parallel
fue mayor que el estándar para cada uno.
¿Por qué crees que .NET solo abrió 1 hilo? ¿Debido al bloqueo de archivo? Gracias
De la descripción del problema, no hay nada que explique por qué la TPL no está generando más subprocesos.
No hay evidencia en la pregunta que sea el problema. Esto puede solucionarse con bastante facilidad: puede registrar el ID de hilo, antes de ingresar al bucle, y como lo primero que hace dentro de su bucle.
Si siempre es el mismo número, es que la TPL no genera subprocesos. Entonces deberías probar diferentes versiones de tu código y qué cambio activa la TPL para serializar todo. Una razón podría ser si hay un pequeño número de elementos en su lista. El TPL particiona su colección, y si tiene solo algunos artículos, puede terminar con un solo lote. Este comportamiento es configurable por cierto.
Podría ser que, sin darse cuenta, esté bloqueando el bucle, entonces verá muchos números diferentes, pero sin aceleración. Luego, simplifique el código hasta que desaparezca el problema.
Es por diseño que Parallel.ForEach puede usar menos hilos de los solicitados para lograr un mejor rendimiento. Según MSDN [link] :
De forma predeterminada, los métodos Parallel.ForEach y Parallel.For pueden usar un número variable de tareas. Por eso, por ejemplo, la clase ParallelOptions tiene una propiedad MaxDegreeOfParallelism en lugar de una propiedad "MinDegreeOfParallelism". La idea es que el sistema puede usar menos hilos de los solicitados para procesar un bucle.
El grupo de subprocesos .NET se adapta dinámicamente a las cargas de trabajo cambiantes al permitir que la cantidad de subprocesos de trabajo para tareas paralelas cambie con el tiempo. En el tiempo de ejecución, el sistema observa si el aumento del número de subprocesos mejora o degrada el rendimiento general y ajusta el número de subprocesos de trabajo en consecuencia.
No siempre la forma paralela es más rápida que la "manera antigua" http://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/c860cf3f-f7a6-46b5-8a07-ca2f413258dd
Sí, exactamente, Document.Load(...)
bloquea el archivo y, debido a la contención de recursos entre los subprocesos, TPL no puede utilizar el poder de varios subprocesos. Intente cargar el XML en una Stream
y luego use Parallel.For(...)
.
utilízalo así:
int ParallelThreads = 10;
Parallel.ForEach(xDoc.Descendants("APSEvent").ToList(), new ParallelOptions() { MaxDegreeOfParallelism = ParallelThreads }, (myXDOC, i, j) =>
{
//do whatever you want here
});