I have a wrapper to the Task.Factory.StartNew, called TaskManager, that I needed to implement in order to add exception handling in the new thread. Here is my class:
public static class TaskManager
{
public static Task StartNew(Action action, IUserContextBase userContext, Action<Task> onCompletedCallback = null)
{
return AddContinueWithToTask(Task.Factory.StartNew(action), userContext, null, onCompletedCallback);
}
public static Task StartNew(Action action, IUserContextBase userContext, CancellationToken cancellationToken, TaskCreationOptions taskCreationOptions, TaskScheduler taskScheduler, Action<Task> onCompletedCallback = null)
{
return AddContinueWithToTask(Task.Factory.StartNew(action, cancellationToken, taskCreationOptions, taskScheduler), userContext, null, onCompletedCallback);
}
public static Task StartNew(Action action, IUserContextBase userContext, TaskCreationOptions taskCreationOptions, Action<Task> onCompletedCallback = null)
{
return AddContinueWithToTask(Task.Factory.StartNew(action, taskCreationOptions), userContext, null, onCompletedCallback);
}
public static Task StartNew(Action<object> action, IUserContextBase userContext, object state, Action<Task> onCompletedCallback = null)
{
return AddContinueWithToTask(Task.Factory.StartNew(action, state), userContext, null, onCompletedCallback);
}
public static Task StartNew(Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions taskCreationOptions, TaskScheduler taskScheduler, Action<Task> onCompletedCallback = null)
{
return AddContinueWithToTask(Task.Factory.StartNew(action, null, cancellationToken, taskCreationOptions, taskScheduler), null, null, onCompletedCallback);
}
public static Task StartNew(Action<object> action, object state, Action<System.Exception> onExceptionCallback = null, Action<Task> onCompletedCallback = null)
{
return AddContinueWithToTask(Task.Factory.StartNew(action, state), null, onExceptionCallback, onCompletedCallback);
}
public static Task StartNew(Action action, Action<System.Exception> onExceptionCallback = null)
{
return AddContinueWithToTask(Task.Factory.StartNew(action), null, onExceptionCallback);
}
public static Task<TResult> StartNew<TResult>(Func<TResult> function, IUserContextBase userContext, CancellationToken cancellationToken)
{
return Task.Factory.StartNew(function, cancellationToken).ContinueWith(t =>
{
ManageException(t, userContext);
return t.Result;
}, TaskContinuationOptions.OnlyOnFaulted);
}
private static void ManageException(Task t, IUserContextBase userContext, Action<System.Exception> onExceptionCallback = null)
{
if (t.Exception != null)
if (onExceptionCallback != null)
onExceptionCallback(t.Exception);
else
t.Exception.Handle(ex =>
{
GlobalContainer.Unity.Resolve<IDiagnosticLogHandler>().LogError(userContext, ex, ErrorSeverity.Normal);
return true;
});
}
private static Task AddContinueWithToTask(Task task, IUserContextBase userContext, Action<System.Exception> onExceptionCallback = null, Action<Task> onCompletedCallback = null)
{
return task
.ContinueWith(t => ManageException(t, userContext, onExceptionCallback), TaskContinuationOptions.OnlyOnFaulted)
.ContinueWith(t2 => { if (onCompletedCallback != null) onCompletedCallback(t2); })
.ContinueWith(t => ManageException(t, userContext, onExceptionCallback), TaskContinuationOptions.OnlyOnFaulted);
}
However, whenever someone uses my class (it returns a Task) and then calls task.Wait() or task.WaitAll() afterwards, they seem to get an exception saying that the tasks have (all) been cancelled. The error occurs at the Wait() or WaitAll(). What could be wrong with my TaskManager class?
Task. You're trapping all exceptions, preventing the users from actually using theTaskto deal with them properly or having the appropriate continuation behavior. As for your error, without knowing how you're using these methods there's no way to reproduce the problem or see what the problem is. - Servy