2016-03-28 47 views
2

我的程序正在創建一些任務來完成一些工作。 現在,我想在我退出程序之前等待所有任務完成。等待動態創建的任務,直到他們完成

我知道Task.WaitAll(...)方法,但在我的情況下,我想動態創建一些任務 - >當調用Task.WaitAll()時,它們不存在。

我現在的問題是: 如何等待所有正在運行的任務,直到它們完成?

這就是我現在要做的。

它的作品,但我想確保這也是一個很好的方法來做到這一點。

public class Test 
{ 
    public ConcurrentBag<Task> RunningTasks { get; set; } 

    public Test() 
    { 
     RunningTasks = new ConcurrentBag<Task>(); 
    } 

    public void RunIt(){ 

     //...create some Tasks asynchronously so they may be created in a few seconds and add them to the list like 
     //RunningTasks.Add(...); 


     //Just wait until all tasks finished. 
     var waitTask = Task.Run(() => 
     { 
      while (true) 
      { 
       if (RunningTasks.All(t => t.IsCompleted)) 
        break; 

       Thread.Sleep(1000); 
      } 
     }); 

     waitTask.Wait(); 

    } 
} 

回答

2

Task.WhenAll()將採取Task陣列,以及ConcurrentBag<T>支持ToArray()擴展方法,所以你可以簡單地做:

await Task.WhenAll(RunningTasks.ToArray()) 

,或者如果你不想使用await關鍵字:

Task.WhenAll(RunningTasks.ToArray()).Wait() 

UPDATE

所以,如果你RunningTasks初始呼叫後,正在改變,你可以做到這一點很容易地處理它:

while(RunningTasks.Any(t=>!t.IsCompleted)) 
{ 
    Task.WhenAll(RunningTasks.ToArray()); 
} 

在你的方法的主要好處是,這將產生線程其他工作在等待,在那裏你的代碼將把線程置於睡眠狀態,直到所有的任務完成。

+0

感謝您的快速回答,但在我的情況下,我將在其他任務內創建任務(我有一些自定義邏輯來創建新的任務)和RunningTasks.ToArray() - 方法僅將當前任務添加到WhenAll-Method 。它將忽略稍後將添加到RunningTasks列表的任務。 –

+0

@TobiasKoller我更新了我的答案。 – CodingGorilla

+0

@CodingGrillla:您的更新解決方案將會發生OutOfMemory-Exception。所以我想我會用我的解決方案。無論如何謝謝你試圖幫助! –