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?
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.
精彩评论