2016-03-28 93 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。所以我想我会用我的解决方案。无论如何谢谢你试图帮助! –