2012-04-11 14 views
0

ich oft seltsam resulst wenn int Variablen Aufgaben wie in diesem Beispiel übergeben:Pass nicht Referenzwert Aufgabe

List<List<object>> ListToProcess = new List<List<object>>(); 

// place some lists in list to process 
foreach (var temp in Foo) 
    ListToProcess.Add(temp); 

foreach (var tempArray in ListToProcess) 
{ 
    // initialize each list in ListToProcess      
} 

int numberOfChunks = ListToProcess.Count; 
Task[] tasks = new Task[numberOfChunks]; 
for (int counter = 0; counter < numberOfChunks; counter++) 
{ 
    tasks[counter] = Task.Factory.StartNew(() => 
     { 
      // counter is always = 5 why? <--------------------------- 
      var t = ListToProcess[counter];       
     }); 
} 

Wie kann ich dieses Problem lösen?

+2

Verschlüsse erfassen Variablen, keine Werte. Siehe http://stackoverflow.com/questions/271440/c-sharp-captured-variable-in-loop –

Antwort

2

Dies ist als ein Verschluss bekannt. Sie verwenden nicht den Wert der Variablen, Sie verwenden die Variable selbst. Wenn der Code ausgeführt wird, verwendet er den Wert zum Zeitpunkt der Ausführung und nicht den Wert, als der Task definiert wurde.

um dieses Problem zu beheben, ich glaube, Sie so etwas tun würde:

for (int counter = 0; counter < numberOfChunks; counter++) 
{ 
    int cur = counter; 
    tasks[counter] = Task.Factory.StartNew(() => 
    { 
     // counter is always = 5 why? <--------------------------- 
     var t = ListToProcess[cur];       
    }); 
} 
1

Es kann nicht garantiert werden, wann auf die Variable 'counter' im Aktionsblock von StartNew zugegriffen wird. Was wahrscheinlich passieren wird ist, dass alle 5 Werte durchlaufen werden, und die Aufgaben erstellt werden, dann werden die Aufgaben ausgeführt.

Wenn sie laufen kann, wird die folgende ausgeführt:

var t = ListToProcess[counter]; 

Aber in diesem Stadium Zahl auf 5 bereits gleich

Vielleicht sollte man sich parallel Sammlungen aussehen?

ListToProcess.AsParallel().ForAll(list => dosomething(list)); 

Es gibt viele andere Optionen in diesem Bereich.

0
for (int counter = 0; counter < numberOfChunks; counter++) 
    { 
     var referenceVariable = new{val=counter}; 
     tasks[counter] = Task.Factory.StartNew(() => 
      { 
       var t = ListToProcess[referenceVariable.val];       
      }); 
    } 
0

Da Variablen erfasst werden, können Sie dies durch erneut deklariert eine neue Variable in jeder Schleife lösen.

for (int counter = 0; counter < numberOfChunks; counter++) 
{ 
    int localCounter = counter; 
    tasks[localCounter] = Task.Factory.StartNew(() => 
     { 
      // counter is always = 5 why? <--------------------------- 
      var t = ListToProcess[localCounter];       
     }); 
} 
Verwandte Themen