Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to continue with task C after A and B run to completion without fault or cancellation using a single TPL method?

I've tried to use Task.Factory.ContinueWhenAll() a few times now with the intent of invoking a continuation only when all the antecedents run to completion without any errors or cancellations. Doing so causes an ArgumentOutOfRangeException to be thrown with the message,

It is invalid to exclude specific continuation kinds for continuations off of multiple tasks. Parameter name: continuationOptions

For example, the code

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());

is not acceptable to the TPL. Is there a way to do something like this using some other TPL method?

like image 588
Kit Avatar asked Dec 07 '10 22:12

Kit


People also ask

What is a continuation task?

A continuation task (also known just as a continuation) is an asynchronous task that's invoked by another task, known as the antecedent, when the antecedent finishes.

What is the difference between task run and task factory StartNew?

Task. Run(action) internally uses the default TaskScheduler , which means it always offloads a task to the thread pool. StartNew(action) , on the other hand, uses the scheduler of the current thread which may not use thread pool at all!

How do you end a task in C#?

First, we need to create an instance of the CancellationTokenSource class as follows. CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); Then we need to set the time interval i.e. when this token is going to cancel the task execution.

What is ContinueWith c#?

The ContinueWith function is a method available on the task that allows executing code after the task has finished execution. In simple words it allows continuation. Things to note here is that ContinueWith also returns one Task. That means you can attach ContinueWith one task returned by this method.


1 Answers

There doesn't appear to be a direct way to do this. I've gotten around this by changing OnlyOnRanToCompletion to None and checking to see if Exception is non-null for each task passed into the continuation. Something like

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

    // otherwise proceed...
}

works, but this doesn't seem to be a very satisfying way to handle the case with multiple antecedents and breaks with the pattern the single-case Task.Factory.ContinueWith uses.

like image 133
Kit Avatar answered Oct 29 '22 08:10

Kit