2011-07-14 60 views
7

做一些小實驗來找出事情是如何工作的。我有以下代碼....net 4.0任務中的私有變量

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

我不知道爲什麼MethodTest接收INT 20幾乎總是(除非我在調試器中單步)。

很明顯,我的理解中缺少一些東西,因爲我認爲當'i'被傳遞時它將成爲託管線程本地存儲的一部分。

回答

15

您關閉了循環變量 - 試試這個:

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

瞭解的重要一點是,你在變i創建一個封閉,並不是它的當前值

當線程池開始第一個線程(它們首先在隊列中)時,變量i幾乎肯定會是20,因爲您已經跳出循環。現在,每個啓動的線程將在當時的時間點處查看變量i的值。

所建議的解決辦法是創建該環路的一個新的變量內部的範圍和i電流值分配給該變量。由於在循環的每次迭代中都使用一個新變量,因此每個創建的線程現在正在關閉其「自己」變量,該變量是隔離的並且不會更改。

解釋發生了什麼的標準參考是「Closing over the loop variable considered harmful」。

+1

+1好問題,很好的答案。 –

+0

謝謝,填補一些知識空白的時間,不知道在哪裏指導我的Google-Fu。 :) – RekrowYnapmoc

+0

編輯:作爲未來讀者的一個筆記。這將在c#5中進行更改,以便關閉循環變量不需要這個額外的步驟。 – RekrowYnapmoc