2012-04-11 70 views
0

我路過INT變量任務時經常會奇怪resulst如下面的例子:傳遞非參考價值任務

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];       
     }); 
} 

我怎樣才能解決這個問題?

+2

閉包捕獲變量,而不是值。 請參閱http://stackoverflow.com/questions/271440/c-sharp-captured-variable-in-loop – 2012-04-11 23:00:00

回答

2

這被稱爲閉包。你沒有使用變量的值,你正在使用變量本身。代碼執行時,它會在執行時使用該值,而不是定義任務時的值。

要解決這個問題,我相信你會做這樣的事情:

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

無法保證何時訪問StartNew的Action塊中的'counter'變量。可能發生的情況是所有5個值都循環遍歷,並且創建任務,然後計劃任務運行。

當他們運行,以下規則執行:

var t = ListToProcess[counter]; 

但現階段數已經等於5

也許你應該看看並行收集?

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

這個地區有很多其他的選擇。

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

自變量被捕獲,您可以通過在每個循環重新聲明一個新的變量解決這個問題。

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