2012-06-19 30 views
14

¿Hay alguna manera fácil de pasar por un parallel.foreach? ¿Cuál es la mejor manera de depurar esto con un punto de quiebre?Parallel.ForEach Debug o Step Through

+1

si no le interesa depurar el paralelismo, y solo quiere comprobar lo que está sucediendo dentro del ciclo, cópielo a un foreach en serie y páselo (comente el paralelo para la producción) – Dimitri

+0

@Dimitri Safer/simpler simplemente hacer que 'Parallel.ForEach' se ejecute secuencialmente para la depuración. –

+0

@Reed - sí, es por eso que he votado a favor su respuesta. Nunca lo había pensado antes. – Dimitri

Respuesta

3

Puede obtener resultados similares con Visual Studio simplemente congelando todos los hilos excepto uno, seleccione todos los hilos excepto uno en la ventana de Subprocesos y haga clic con el botón derecho -> Congelar como este:

enter image description here

Además, si se quiere reproducir una condición de carrera y detenerse en los puntos de ruptura se rompe, siempre se puede añadir Tracepoints - ya sea con el estudio visual o con plugins que ayudan con ella, tales como Código Oz

enter image description here

0

Reescriba temporalmente como un foreach no paralelo, o utilice directivas de preprocesador para ejecutar código no paralelo cuando se ejecuta en modo de depuración.

26

Durante la depuración, a menudo configuro mi Parallel.ForEach para ejecutar con MaxDegreeOfParallelism en 1. Esto hace que sea mucho más simple de depurar.

const bool forceNonParallel = true; 
var options = new ParallelOptions { MaxDegreeOfParallelism = forceNonParallel ? 1 : -1 }; 
Parallel.ForEach(collection, options, item => 
{ //... 

Sin embargo, esto no va a ayudar con problemas de depuración relativa a las condiciones de carrera o la sincronización de datos, y, de hecho, a menudo ocultar o eliminar los problemas reales en su código.

Esas cuestiones a menudo se pueden depurar mucho más fácilmente mediante el uso de las nuevas herramientas de VS 2010, tales como el Parallel Tasks window, o mediante el uso de las diversas técnicas que figuran en Debugging Multithreaded Applications, como switching threads, hilos de bloqueo de tiempo que se refuerza, etc.

+0

¿Conoces alguna documentación para "-1"? El artículo msdn dice que se lanzará un error si se establece en 0 o en cualquier valor por debajo de -1, pero no explica el -1. – granadaCoder

+0

@granadaCoder Consulte https://msdn.microsoft.com/en-us/library/system.threading.tasks.paralleloptions.maxdegreeofparallelism%28v=vs.110%29.aspx "Si es -1, no hay límite en el número de operaciones simultáneas en ejecución ". –

+0

Ga! No leí lo suficiente. Gracias. – granadaCoder

0

Me gusta utilizar la opción "Cuándo golpear" en un punto de interrupción (haga clic con el botón secundario en el punto de interrupción, seleccione "Al recibir ...". Puede imprimir un mensaje en la consola que incluya valores de variables, el hilo en el que se encuentra , etc.

5

Al igual que otras respuestas aquí, establecemos el grado de paralelismo en 1 cuando se depura, pero lo hacemos con un método de extensión, como:

public static ParallelQuery<TSource> AsDebugFriendlyParallel<TSource>(this IEnumerable<TSource> source) 
{ 
    var pQuery = source.AsParallel(); 
    #if DEBUG 
    pQuery = pQuery.WithDegreeOfParallelism(1); 
    #endif 

    return pQuery; 
} 

Entonces, en lugar de utilizar .AsParallel() utilizamos .AsDebugFriendlyParallel()