I'm working on a Web Hook in .NET 4.0 that will run a lambda asynchronously and then post the result to a given URI when it is finished.
I've got that to work, but now I want the Task to handle any exceptions that are thrown, and am finding it difficult to stop them from reaching the parent.
Here's part of my code:
private readonly Func<T> _startTask;
private readonly string _responseUri;
public Task<T> Begin()
{
var task = new Task<T>(_startTask);
task.ContinueWith<T>(End);
task.Start();
return task;
}
private T End(Task<T> task)
{
if (task.IsFaulted)
{
return HandleException(task);
}
var result = task.Result;
WebHookResponse.Respond(result, _responseUri);
return result;
}
private T HandleException(Task<T> task)
{
WebHookResponse.HandleException(task.Exception.InnerException, _responseUri);
return null;
}
An alternative version that I have tried calls ContinueWith()
twice to register one continuation to run OnlyOnRanToCompletion
and one to run OnlyOnFaulted
. (I'm not sure if calling ContinueWith()
twice is correct.):
public Task<T> Begin()
{
var task = new Task<T>(_startTask);
task.ContinueWith<T>(End, TaskContinuationOptions.OnlyOnRanToCompletion);
task.ContinueWith<T>(HandleException, TaskContinuationOptions.OnlyOnFaulted);
task.Start();
return task;
}
private T End(Task<T> task)
{
var result = task.Result;
WebHookResponse.Respond(result, _responseUri);
return result;
}
private T HandleException(Task<T> task)
{
WebHookResponse.HandleException(task.Exception.InnerException, _responseUri);
return null;
}
So basically I want a way for each Task handle its own exceptions via a continuation function. As it stands the HandlException continuation function is never being called in either of the above examples.
I am causing the exceptions in a test case, and I should mention that I am using a Tasks.WaitAll(tasks);
call on an array of Tasks to make sure all of the tasks are complete before making my assertions, and I am not sure if that call makes a difference to how exceptions are handled by the Tasks. Currently WaitAll throws an AggregationException which aggregates the exceptions for each of the Tasks because they aren't being handled by the HandleException continuation function.