2011-11-06 43 views
2

我想在線程列表中運行具有不同值的類。像這樣:線程輸入參數

 int index = 0; 
    foreach (TreeNode nd in tvew.Nodes[0].Nodes) 
    { 
     threadping[index] = new Thread(delegate() 
     { this.Invoke(new DelegateClientState(InvokeCheckNetworkState), new object[] {nd}); }); 

     threadping[index].Name = nd.Name; 
     threadping[index].IsBackground = true; 
     threadping[index].Start(); 

     index++; 
    } 

但是當我調試代碼時,我看到類參數只是最後一個值。 我的意思是,當我通過線程類時,我發現每次運行輸入參數的值都是最後一個線程的最後一個值。

有人可以告訴我爲什麼?

+0

你可以顯示你已經初始化threadPing集合的代碼。什麼是「類參數」或者你正在調試什麼線程類? –

回答

5

這是因爲nd變量是在閉包中捕獲的。線程運行時,它們都引用相同的TreeNode實例,即分配給nd的最後一個實例。要修復,使用單獨的變量,沒有範圍內改變:

foreach (TreeNode nd in tvew.Nodes[0].Nodes) 
{ 
    var current = nd; 
    threadping[index] = new Thread(delegate() 
    { this.Invoke(new DelegateClientState(InvokeCheckNetworkState), new object[] {current}); }); 

如果我們得到的編譯器技術,這是因爲編譯器生成包含您的循環變量,以使其成爲訪問的匿名類線程委託。這是預期的行爲,但可能在第一次遇到它時有點違反直覺。

有關閉包和變量捕獲的更長解釋,請參閱see the Captured Variables section here (bottom section) in a Jon Skeet articlethis article from Eric Lippert。這通常稱爲「訪問修改的關閉」錯誤。如果你在StackOverflow或Google上搜索這個詞,你會得到很多解釋它的命中。

+0

tnx,它的工作原理。另一個問題:爲什麼我的線程不能同時工作?我在第一個循環結束時提出的「InvokeCheckNetworkState」的第一行指向斷點。就像線程等待上一個線程完成一樣。我的意思是你不同時工作。我該怎麼辦? –