2016-03-28 2 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 , Он будет игнорировать задачи, которые будут добавлены в список RunningTasks позже. –

+0

@TobiasKoller Я обновил свой ответ. – CodingGorilla

+0

@CodingGrillla: Ваше обновленное решение будет иметь случай OutOfMemory-Exception. Поэтому я предполагаю, что буду использовать свое решение. В любом случае спасибо за попытку помочь !! –

Смежные вопросы