domingo, 8 de febrero de 2015

!Apunte semanal - Problemas al depurar tareas en paralelo?


Hola amigos, en anteriores artículos tuvimos una introducción al paralelismo, y mucho más enfocado en lo que Microsoft .Net nos ofrece para trabajar con él, en resumidas cuentas tenemos la TPL que es la librería que nos permite trabajar con paralelismo de una forma muy sencilla, y que nos ofrece varias formas de trabajo como lo son el trabajo con datos a través de ciclos paralelos, paralelismo a través de tareas (Task), Plinq que nos permite realizar consultas linq en paralelo, entre otras. Y entre estas formas de trabajo hay una en particular que se convierte en transversal para todas, y es la depuración de procesos en paralelo, de suma importancia y utilidad para llevar un paso a paso de las instrucciones en las cuales estemos empleando el paralelismo, ya que en este tipo de instrucciones en paralelo podemos tener problemas a la hora de depurar, ya que cuando estamos haciendo paso a paso de una instrucción en ocasiones el depurador se salta y va a otra instrucción que se está ejecutando en simultánea, y luego vuelve a anterior, con lo cual tenemos un gran problema para comprender y seguir la depuración de una tarea en específico, yo por ejemplo he tenido este problema cuando trabajo referenciando dlls de otros proyectos de los cuales no tengo los proyectos agregados en la solución que estoy depurando.


Pues bueno para solucionar este problema si es que se nos presenta, podemos usar la clase Debugger del NameSpace System.Diagnostics, la cual nos permitirá hacer un punto de ruptura a través del método Break(), veamos cómo lo podemos hacer:

Primero vamos a crear en una aplicación de consola con una ejecución de tareas que invoquen diferentes métodos, tal como vemos a continuación:

        static void Main(string[] args)
        {
            Task t = new Task(TareaA);
            t.Start();
 
            Task t2 = new Task(TareaB);
            t2.Start();
 
            Task t3 = new Task(TareaC);
            t3.Start();
 
            Task.WaitAll(new Task[] { t, t2, t3 });
            Console.Write("Terminó la ejecución de las tareas A, B y C.");
        }

 Y ahora vamos usar un punto de ruptura en alguna de las tareas:

        private static void TareaA()
        {
            Debugger.Break();
            Thread.Sleep(2000);
            Console.Write("Se ejecutó la tárea A");
        }

Con este Debugger.Break() ahora podemos depurar el contenido de la tarea A, sin tener problemas de con las otras tareas que se ejecutan en paralelo, adicional también nos podría ser de utilidad cuando tenemos instrucciones muy tediosas de depurar, por ejemplo si estamos recorriendo una lista de 10000 ítems y tenemos un error que solo se genera con alguno de los ítems, podríamos realizar una condicional y usar el Debugger.Break para capturar con mayor facilidad el problema (aunque también lo podríamos hacer con las condicionales que nos ofrecen los puntos de interrupción de Visual Studio).

Bueno y eso es todo de este apunte semanal, espero sea de utilidad.

Saludos y buena suerte!

No hay comentarios:

Publicar un comentario