2011-11-01 79 views
1

我一直在玩線程和任務(.net 4),並注意到一些奇怪的行爲,當你啓動多個線程,而不用等待幾個毫秒之間的每個線程開始調用。啓動多個線程,爲什麼你必須等待?

在運行時不輸出下面的例子我所期待的:

1 
2 
1 
2 

而只是輸出:

2 
2 
2 
2 

下面是我運行的代碼。

public static void Main() 
{ 
    var items = new[] {"1", "2"}; 
    foreach (var item in items) 
    { 
     var thread = new Thread(() => Print(item));   
     thread.Start(); 
     //var task = Task.Factory.StartNew(() => Print(item));    
    } 
} 

static void Print(string something) 
{ 
    while (true) 
    { 
    Console.WriteLine(something); 
    Thread.Sleep(1000); 
    } 
} 

現在,當我打電話thread.Start(後Thread.sleep代碼(50)),那麼不僅會如預期的輸出看

1 
2 
1 
2 

我的問題是:

  • 爲什麼當你在啓動兩個線程之間沒有等待時,第一個線程是否鬆開了你最初使用的方法參數值?

即第一個線程以參數「1」啓動,第二個線程以參數「2」啓動,但是第一個線程的參數也變成了「2」?這沒有任何意義,特別是因爲Print()方法參數是字符串的值類型。

+0

謝謝你所有的答覆。 – TheLegendaryCopyCoder

回答

5

谷歌「訪問修改關閉」。發生了什麼事是你的本地變量「item」正在調用print函數之前改變它的值。一個解決方案是在循環範圍內創建一個新變量併爲其分配項目。

2

該項目在您創建的線程由於c#關閉而啓動時進行評估。給力的項目評估的另一種方法是引入一個變量,以便關閉將包括它像這樣:

foreach (var item in items)  
     { 
      var closedItem = item; 
      var thread = new Thread(() => Print(closedItem));     
      thread.Start();  
     } 
0

我們展示線程開始的代碼,你會發現,你不通過一個常量字符串,但一個引用變量,並且在調用那些Start方法之間,你可能正在改變這個變量。