2011-07-14 5 views
7

haciendo un poco de experimentación para descubrir cómo funcionan las cosas. Tengo el siguiente código ...Variables privadas en .net 4.0 tareas

for (int i = 0; i < 20; i++) 
{ 
     Task.Factory.StartNew(() => MethodTest(i)); 
} 

me pregunto por qué MethodTest recibe la int 20 casi siempre (a menos que esté pasando a través de depurador).

Obviamente, falta algo en mi comprensión ya que asumí que cuando se pase 'i' sería parte del almacenamiento local de un hilo administrado.

Respuesta

15

Se dispone a cerrar sobre la variable de bucle - intente esto:

for (int i = 0; i < 20; i++) 
{ 
     int x = i; 
     Task.Factory.StartNew(() => MethodTest(x)); 
} 

Lo importante a entender es que se está creando un cierre sobre la variablei, y no su valor actual.

En el momento en que el grupo de subprocesos está iniciando el primer subproceso (que primero cae en la cola) la variable i será casi seguramente 20 ya que ha salido del ciclo. Ahora cada hilo que se inicia verá el valor de la variable ien ese momento.

La solución sugerida es crear una nueva variable dentro de el alcance del ciclo y asignar el valor actual de i a esa variable. Como se usa una nueva variable en cada iteración del ciclo, cada hilo creado se está cerrando sobre su propia variable, que está aislada y no cambiará.

La referencia estándar para explicar lo que está pasando es "Closing over the loop variable considered harmful".

+1

+1 Buena pregunta, buena respuesta. –

+0

Gracias, es hora de llenar algunos vacíos de conocimiento, no tenía idea a dónde dirigir mi Google-Fu. :) – RekrowYnapmoc

+0

Editar: como una nota para los lectores futuros. Esto se modificará en C# 5, de modo que el cierre sobre la variable de bucle no requerirá este paso adicional. – RekrowYnapmoc