Pruebas con multiples hilos.

La necesidad de realizar pruebas de concurrencia sobre un componente/servicio de mi aplicación, me hicieron ver la necesidad de buscar una forma de lanzar múltiples hilos que realicen las peticiones que deseaba. Sé que varios o muchos de Uds. ya conocen esto, pero lo que escribo a continuación es más para aquellos que están aprendiendo.

El código básico que encontré en Internet es el siguiente:

 

1 foreach (Thread thread in threads) 2 { 3 thread = new Thread(DoSomeWork()); 4 } 5 foreach (Thread thread in threads) 6 { 7 thread.Start(); 8 } 9 foreach (Thread thread in threads) 10 { 11 thread.Join(); 12 }

 

Este código lo tome de una entrada de stackoverflow, y tiene dos cosas importantes: Una es la línea 11 que permite esperar a que todos los hilos terminen su operación y el otro punto es que tiene un error, la línea 3 dará un error porque se está tratando de modificar un objeto read-only, al menos eso es lo que yo obtuve. Ante todo esto me permito presentarles una versión ligeramente modificada, que actualmente estoy utilizando:

 

1 static void MultiThreadedTest(int count) 2 { 3 Thread[] threads = new Thread[count]; 4 for (int i = 0; i < threads.Count(); i++) 5 { 6 var j = i; 7 ThreadStart starter = delegate { DoSomeWork(j); }; 8 threads[i] = new Thread(starter); 9 } 10 foreach (Thread thread in threads) 11 { 12 thread.Start(); 13 } 14 foreach (Thread thread in threads) 15 { 16 thread.Join(); 17 } 18 }

He encerrado toda la funcionalidad en un método, he reemplazado el bloque foreach por un for simple, que me permite evitar el problema del read-only. En las líneas 7 y 8 estoy inicializando los hilos parametrizados con el valor numérico, hay varias formas de hacer esto pero la que les presento en el ejemplo es la que yo escogí. Luego hay una línea que parecería sin sentido, es la linea 6, esta línea evita el problema del acceso a un closure modificado (“Access to modified closure”), por cierto esta advertencia me la da Resharper. Que significa esto?, pues si no se coloca esa línea el valor que se pase al método DoSomeWork siempre será el ultimo valor del bucle. Ya tuve malas experiencias con las expresiones lambda y estas advertencias, así que para evitarme problemas… que me cuesta agregar una línea!!!?

Finalmente el método DoSomeWork, que es el que realizara el acceso a mi servicio en última instancia.

 

1 private static void DoSomeWork(int number) 2 { 3 //..... 4 }

 

Espero que le sea de utilidad a alguien que este realizando pruebas con multiples hilos.

Saludos.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *