2013-02-10 3 views
6

У меня есть цикл, который создает несколько задач, как показано ниже. Как обновить экран (добавить новую строку в текстовое поле с некоторыми данными) по мере завершения каждой задачи?Задание задачи

Как определить, когда все задачи завершены?

C# Код

for (int i = 0; i < int.Parse(radTextBoxFloodRequests.Text); i++) 
{ 
     int x = i; 
     // Create a task and supply a user delegate by using a lambda expression. 
     var taskA = new Task(() => TaskRequest(int.Parse(radTextBoxFirstNumber.Text), int.Parse(radTextBoxSecondNumber.Text), int.Parse(radTextBoxFloodDelay.Text), x)); 
     // Start the task. 
     taskA.Start(); 
} 


private void TaskRequest(int number1, int number2, int delay, int count) 
{ 
     // Some long running method 
} 
+1

Вы хотите получить триггер, когда все ваши задачи выполнены? – bas

+0

да, и по мере выполнения каждой задачи также – user1438082

+1

Are Parallel.For или Parallel.ForEach решение для вас? Трудно понять, что вы ищете. – bas

ответ

13

Вы можете использовать ContinueWith():

"Создает продолжение, которое выполняется асинхронно, когда целевая задача завершается." - MSDN

Task t = new Task(() => Console.WriteLine("")).ContinueWith(task => Console.Writeline("Continue With"), 
                  TaskScheduler.FromCurrentSynchronizationContext()); 
+4

Вам нужно добавить параметр TaskScheduler.FromCurrentSynchronizationContext, если вы собираетесь обновлять пользовательский интерфейс, вы можете быть в другом потоке. – Jesse

+0

как я могу поместить это в свой код? – user1438082

+0

Перед последним скобкой добавьте «, TaskScheduler.FromCurrentSynchronizationContext» – Jesse

1

Я рекомендую вам использовать комбинацию 3 простых конструкций:

  • простой int numActiveTasks, который увеличивается с InterlockedIncrement(ref numActiveTasks) на создании задачи, то есть непосредственно перед taskA.Start() и декрементируется с InterlockedDecrement(ref numActiveTasks) в конце задачи, то есть в конце функции TaskRequest(...)
  • a ManualResetEvent, который сбрасывается перед запуском задачи и сигнализирует о завершении задачи после счетчика уменьшает
  • нити, что WaitOne() s на ManualResetEvent, затем читает numActiveTasks

Это дает

  • notfication единой задача сделала
  • уведомление о всех выполненных задачах (numActiveTasks < = 0)

Главное преимущество этого заключается в том, что у вас есть суверенитет о том, в какой нити это уведомление происходит.

+0

привет, можете ли вы предоставить некоторый код для этого, чтобы проиллюстрировать, как это делается? – user1438082

1

Вы ищете Parallel.ForEach()?

[Test] 
    public void ParallelTasks() 
    { 
     var strings = new List<string> {"task1", "task2", "task3"}; 

     Parallel.ForEach(strings, str => Console.WriteLine(str + "is done")); 

     // All your parallel tasks are executed now 
    } 
1

Расширяясь от ответа пользователя 12345678, вы можете сделать что-то вроде ниже.

private void RunTasks() 
    { 
     Dictionary<string, string> dict = new Dictionary<string, string>(); 

     List<Task> tasks = new List<Task>(); 
     foreach (KeyValuePair<string,string> kvp in dict) 
     { 
      Console.WriteLine("Executing task " + kvp.Key + " ..."); 
      Task t = new Task(() => MyMethod(kvp.Key, kvp.Value)); 
      tasks.Add(t); 
      t.Start(); 
      t.ContinueWith(task => Console.WriteLine(kvp.Key + " completed")); 

     } 

     Console.WriteLine("Waiting tasks to complete..."); 
     Task.WaitAll(tasks.ToArray()); 
     Console.WriteLine("All tasks completed..."); 
    } 

    private void MyMethod(string arg1, string arg2) 
    { 

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