2012-05-23 5 views
5

Привет, у меня есть _noOfThreads как определенные задачи для запуска одновременно. Поэтому я продолжаю выполнение задач с помощью оператора %, и в конце цикла у меня есть Tasks.WaitAll. Это фрагмент кода.Task.WaitAll не ждет дочерней задачи?

for (int index = 0; index < count; index++) 
{ 

       if (index < _noOfThreads) 
        tasks[index] = Task.Factory.StartNew(somedelegate); 
       else 
        tasks[index % _noOfThreads].ContinueWith(task => { foo.bar(); }, 
          TaskContinuationOptions.AttachedToParent); 
} 
    Task.WaitAll(tasks); 

Однако, я замечаю, что он не дожидается завершения дочерних задач. Как только родительские задачи завершатся, выполняется следующая строка после Task.WaitAll. Как изменить этот код, чтобы дождаться дочерних задач?

+0

Возможный дубликат [Task.ContinueWith не работает, как я ожидал] (http://stackoverflow.com/questions/6997480/task-continuewith-not-working-how-i-expected) – mellamokb

+0

На боковой ноте, что вы, кажется, здесь делаете решение планирования задач. Если вы хотите настроить планирование, вы можете посмотреть на [TaskScheduler] (http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler.aspx). Тем не менее, планировщик по умолчанию уже делает довольно хорошую работу, не перегружая систему потоками, когда большое количество задач поставлено в очередь. –

+0

@ Dan: Это не мое беспокойство. Я не знаю, хочу ли это передать TaskScheduler. У меня есть переменная, и я хочу запускать задачи только по той же переменной. Короче говоря, я хочу симулировать что-то вроде Semaphore, где вы определяете количество потоков, и только определенное количество потоков может ввести этот фрагмент кода в определенное время. –

ответ

8

Я думаю, что вы направляете свои задачи как:

Tasks[] tasks = new Task[ _noOfThreads]; 

Изменить код будет:

Tasks[] tasks = new Task[count]; 

for (int index = 0; index < count; index++) 
{ 

    if (index < _noOfThreads) 
     tasks[index] = Task.Factory.StartNew(somedelegate); 
    else 
     tasks[index] = tasks[index % _noOfThreads].ContinueWith(task => { foo.bar(); }, 
          TaskContinuationOptions.AttachedToParent); 
} 
Task.WaitAll(tasks); 

Дайте ему попробовать! Удачи :)

3

Вы ожидаете первоначальной работы. Чтобы дождаться завершения всех продолжений, вам нужно позвонить WaitAll о задачах продолжения. Простой способ для достижения этой цели будет переназначить каждую задачу продолжения назад к исходной переменной, так что вы ждете только на конечных продолжениях:

else 
    tasks[index % _noOfThreads] = 
     tasks[index % _noOfThreads].ContinueWith(task => { foo.bar(); }, 
         TaskContinuationOptions.AttachedToParent); 

Смотрите также this related question.

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