2013-02-19 132 views
0

我正在做一些C#線程。沒有任何問題啓動線程並將數據傳輸給它們,但我在等待它們結束時遇到問題。等待線程結束的問題

我的代碼如下所示。我使用Join()來等待線程結束,但由於某種原因,我的代碼無法工作。

儘管在所有活動線程上調用Join(),主線程(即for循環)仍未被阻止。

任何想法,我做錯了嗎?

List<Thread> calculationThreads = new List<Thread>(); 

foreach (string calculation in calculations) 
{ 
    if (calculationThreads.Count < 5) 
    { 
     Thread calculationThread = new Thread(DoCalculation); 
     calculationThreads.Add(calculationThread); 

     calculationThread.Start(threadData); 
    } 
    else 
    { 
     // Wait for the threads to complete 
     foreach (Thread calculationThread in calculationThreads) 
     { 
      calculationThread.Join(); 
     } 
    } 
} 
+2

確定計算線程沒有全部終止? – 2013-02-19 08:49:47

+1

您是否考慮過使用任務並行庫來處理線程,而不是像這樣明確地執行它?很多有用的方法讓你的生活變得更加簡單:http://msdn.microsoft.com/en-us/library/dd537609.aspx – Paddy 2013-02-19 08:50:48

+0

我認爲你應該在加入後從CalculationThreads集合中刪除線程。 – fofik 2013-02-19 08:53:12

回答

2

的第一個問題是你的else箱子處理。如果已經有五個線程,代碼將等待線程完成,但是它試圖添加的任務永遠不會被添加。它只會拋棄該任務並繼續下一步。

第二個問題是你不會從列表中刪除任何線程,所以一旦它達到五個線程,它將永遠等待。如果第一個問題沒有放棄其餘的任務,你的程序就會鎖定。

另外,在繼續工作之前等待所有五個線程完成,您正在浪費處理時間,但這是一個較小的問題。

+0

處理時間是浪費了,但是如果線程產生的數據中存在任何依賴關係,那麼序列應該在for循環之後等待。 – 2013-02-19 09:09:32

+1

@StianStandahl:是的,當最後一項任務處理到一個線程時,您必須等待所有步驟完成才能使用結果,這是不可避免的。然而,現在的代碼會以五人一組的方式削減任務,併爲每個團隊獲得浪費。 – Guffa 2013-02-19 09:14:28

0

我會去一些方法,我只是計算有多少線程我已經開始在每個線程結束時,我降低了櫃檯。

然後在你的循環的開始,你可以有

while(counter >= 5) 
{ 
//Wait 
} 
0

你可以有一個while循環等待所有線程結束。

List<Thread> calculationThreads = new List<Thread>(); 

foreach (string calculation in calculations) 
{ 
    if (calculationThreads.Count < 5) 
    { 
     Thread calculationThread = new Thread(DoCalculation); 
     calculationThreads.Add(calculationThread); 

     calculationThread.Start(threadData); 
    } 
    else 
    { 
     // Wait for the threads to complete 
     while(calculationThread.Any(x => x.IsAlive)){} 
     // Clearing the list 
     calculationThread.Clear(); 
    } 
} 

如果你想保持線程後for循環,你應該有另一個列表用於存儲線程。

+0

哎。你絕對不應該有一個繁忙的循環等待線程完成。 – Guffa 2013-02-19 09:08:17

+0

我知道。應該可能在某處有一個超時函數;) – 2013-02-19 09:10:35

0

您提供給該方法的計算有多少?

閱讀代碼,如果你提供了4個計算,你將開始4個線程,但從來沒有真正去到你做線程的代碼.Join()。

移動if else語句外的thread.join循環。

List<Thread> calculationThreads = new List<Thread>(); 

    foreach (string calculation in calculations) 
    { 
     if (calculationThreads.Count < 5) 
     { 
      Thread calculationThread = new Thread(DoCalculation); 
      calculationThreads.Add(calculationThread); 

      calculationThread.Start(threadData); 
     } 

    } 
    foreach (Thread calculationThread in calculationThreads) 
    { 
     calculationThread.Join(); 
    }