Что мешает Task.Factory.ContinueWhenAll вызвать указанное действие? - PullRequest
1 голос
/ 26 августа 2011

Возьми этот сегмент.

IEnumerable<Task> tasks = CreateTierCleanupTasks();
if (tasks.Count() > 0) {
    Task.Factory.ContinueWhenAll(tasks.ToArray(), OnTierCleanupCompleted,
        m_CancellationTokenSource.Token,
        TaskContinuationOptions.None,
        m_TaskScheduler);
    Array.ForEach(tasks.ToArray(), (t) => t.Start()); 
    OnTierCleanupStarted();
}

А вот и указанное действие.

private void OnTierCleanupCompleted(Task[] tasks) {
    if (tasks.All(task => task.IsCompleted) && TierCleanupCompleted != null) {
        TierCleanupCompleted(this, new EventArgs());
    }
    RunTierData();
}

Сейчас в тестовом прогоне обычно создается 5 задач, и все они работают правильно. Я поставил Debug.WriteLine("Task Return"); в конце тела функции, чтобы убедиться, что каждая задача возвращается соответственно. Действие, указанное для ContinueWhenAll, выполняется , а не . Я не могу понять, почему. Я думал, что поведение ContinueWhenAll вызовет действие, когда все указанные действия вернулись (т.е. завершены).

Что помешает ContinueWhenAll запустить действие?

Правка, вот метод, который создает задачи:

private IEnumerable<Task> CreateTierCleanupTasks() {
    using (FaultTrackObjectContext context = new FaultTrackObjectContext(this.TierInformation.EntityConnectionString)) {
        foreach (TeamCollection collection in context.TeamCollections.ToArray()) {
            yield return new Task(DeleteTeamCollection, collection.ID, m_CancellationTokenSource.Token);
        }
    }
}

1 Ответ

1 голос
/ 27 августа 2011

Проблема в том, что вы повторяете результат CreateTierCleanupTasks() несколько раз.И каждый раз он создает новый набор Task с.Итак, вы ожидаете выполнения некоторых задач, но начинаете другие.

Ваш код должен выглядеть следующим образом:

Task[] tasks = CreateTierCleanupTasks().ToArray();
if (tasks.Length > 0) {
    Task.Factory.ContinueWhenAll(tasks, OnTierCleanupCompleted,
        m_CancellationTokenSource.Token,
        TaskContinuationOptions.None,
        m_TaskScheduler);
    OnTierCleanupStarted();
    Array.ForEach(tasks, (t) => t.Start()); 
}
...