Reputation: 4845
I have this simple TPL code:
var t = Task.Factory.StartNew(() => { throw null; })
.ContinueWith((ant) => { Console.WriteLine("Success"); },
TaskContinuationOptions.OnlyOnRanToCompletion)
.ContinueWith((ant) => { Console.WriteLine("Error"); },
TaskContinuationOptions.OnlyOnFaulted);
t.Wait();
I get an unhandled exception:
Unhandled Exception: System.AggregateException: One or more errors occurred.
...
If i put t.Wait()
in a try-catch
, the exception is caught there and i know it defies the whole point of using the exception continuation. Now, if i remove the completion continuation, the exception thrown by the task is handled in the exception continuation and i don't get the above exception. Can someone throw some light on whats happening?
I am using VS2010 SP1 with .NET 4.0
Upvotes: 0
Views: 413
Reputation: 244757
ContinueWith()
doesn't return the original Task
, it returns a Task
representing the continuation. And in your case that continuation is canceled, because the original Task
didn't run to completion. And because the second Task
wasn't faulted, your third Task
was canceled too, which is why you're getting TaskCanceledException
wrapped inside AggregateException
.
What you can do instead is to have one continuation, which does both actions. Something like:
var t = Task.Factory.StartNew(() => { throw null; })
.ContinueWith(
ant =>
{
if (ant.IsFaulted)
Console.WriteLine("Error");
else
Console.WriteLine("Success");
});
If you do something like this often, you could create an extension method for this (plus probably a generic version for Task<T>
with Action<T>
as onSuccess
):
public static Task ContinueWith(
this Task task, Action onSuccess, Action<AggregateException> onError)
{
return task.ContinueWith(
ant =>
{
if (ant.IsFaulted)
onError(task.Exception);
else
onSuccess();
});
}
Usage:
var t = Task.Factory.StartNew(() => { throw null; })
.ContinueWith(
() => { Console.WriteLine("Success"); },
ex => { Console.WriteLine("Error"); });
t.Wait();
Also, this assumes you know your original Task
won't be canceled. If that's not the case, that's one more case you need to handle.
Upvotes: 3