2012-03-08 30 views
10

Duplicar posibles:
C# Captured Variable In LoopConfundido acerca de múltiples hilos en un bucle para C#

soy bastante nuevo en la programación multi-threading. Cuando ejecuté el código siguiente y solo se ejecutó el último hijo. ¿Puede alguien decirme qué pasó? Muchas gracias.

private void Process() 
{ 
    Dictionary<int, int> dataDict = new Dictionary<int, int>(); 
    dataDict.Add(1, 2000); 
    dataDict.Add(2, 1000); 
    dataDict.Add(3, 4000); 
    dataDict.Add(4, 3000); 

    foreach (KeyValuePair<int, int> kvp in dataDict) 
    { 
     Console.WriteLine("Ready for [" + kvp.Key.ToString() + "]"); 
     Task.Factory.StartNew(() => DoSomething(kvp.Value, kvp.Key)); 
    } 

private static void DoSomething(int waitTime, int childID) 
{ 
    {    
     Console.WriteLine("Start task [" + childID.ToString() + "]"); 
     Thread.Sleep(waitTime); 
     Console.WriteLine("End task [" + childID.ToString() + "]"); 
    } 
} 

salida


Ready for [1] 
Ready for [2] 
Ready for [3] 
Ready for [4] 
Start task [4] 
Start task [4] 
Start task [4] 
Start task [4] 
End task [4] 
End task [4] 
End task [4] 
End task [4] 
+0

Ya, aplicación de consola. – Dreteh

Respuesta

12

Mediante el uso de la variable de bucle en su lambda, toda la refieren efectivamente a la misma variable, que es el último artículo de su diccionario en el tiempo que corren

Debe asignar la variable de bucle a otra variable local al bucle antes de pasarla a una lambda. Haga esto:

foreach (KeyValuePair<int, int> kvp in dataDict) 
{ 
    var pair = kvp; 
    Console.WriteLine("Ready for [" + pair.Key.ToString() + "]"); 
    Task.Factory.StartNew(() => DoSomething(pair.Value, pair.Key)); 
} 

EDITAR: Parece que este pequeño error se ha resuelto en C# 5. Es por eso que podría funcionar para otros;) Ver el comentario por labroo

+2

personas realmente deberían explicar por qué downvoted, parece una explicación razonable para mí –

+2

Por qué downvote, no sé si esta es la solución, pero es un cambio válido ....... http: //blogs.msdn .com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx – labroo

+0

Me preguntaba, también. No puedo ver nada mal con mi respuesta. – Botz3000

1

Puede evitar ese comportamiento asignando kvp a una variable local en el ciclo for y pasar los campos de variables Key y Value al método DoSomething.

+0

Gracias. Pensé que también, pero simplemente no entiendo por qué. – Dreteh

Cuestiones relacionadas