Можно ли продолжить выполнение задачи C после выполнения A и B без сбоев или отмены с использованием одного метода TPL?

Я пытался использовать Task.Factory.ContinueWhenAll() несколько раз с намерением вызвать продолжение только тогда, когда все антецеденты выполняются до завершения без каких-либо ошибок или отмен. Это приводит к возникновению ArgumentOutOfRangeException вместе с сообщением,

Нельзя исключать определенные виды продолжения для продолжения нескольких задач. Имя параметра: continueOptions

Например, код

var first = Task.Factory.StartNew<MyResult>(
    DoSomething,
    firstInfo,
    tokenSource.Token);
var second = Task.Factory.StartNew<MyResult>(
    DoSomethingElse,
    mystate,
    tokenSource.Token);
var third = Task.Factory.ContinueWhenAll(
    new[] { first, second },
    DoSomethingNowThatFirstAndSecondAreDone,
    tokenSource.Token,
    TaskContinuationOptions.OnlyOnRanToCompletion, // not allowed!
    TaskScheduler.FromCurrentSynchronizationContext());

неприемлемо для TPL. Есть ли способ сделать что-то подобное, используя какой-либо другой метод TPL?


person Kit    schedule 07.12.2010    source источник


Ответы (1)


Кажется, что нет прямого способа сделать это. Я обошел это, изменив OnlyOnRanToCompletion на None и проверив, является ли Exception ненулевым для каждой задачи, переданной в продолжение. Что-то типа

private void DoSomethingNowThatFirstAndSecondAreDone(Task<MyResult>[] requestTasks)
{
    if (requestTasks.Any(t => t.Exception != null))
        return;

    // otherwise proceed...
}

работает, но это не кажется очень удовлетворительным способом обработки случая с несколькими антецедентами и разрывами с шаблоном, который использует Task.Factory.ContinueWith для одного случая.

person Kit    schedule 03.03.2011