With System.Threading.Tasks.Task<TResult>, I have to manage the exceptions that could be thrown. I’m looking for the best way to do that. So far, I’ve created a base class that manages all the uncaught exceptions inside the call of .ContinueWith(...)
I’m wondering if there’s a better way do do that. Or even if it is a good way to do that.
public class BaseClass
{
protected void ExecuteIfTaskIsNotFaulted<T>(Task<T> e, Action action)
{
if (!e.IsFaulted) { action(); }
else
{
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
{
/* I display a window explaining the error in the GUI
* and I log the error.
*/
this.Handle.Error(e.Exception);
}));
}
}
}
public class ChildClass : BaseClass
{
public void DoItInAThread()
{
var context = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew<StateObject>(() => this.Action())
.ContinueWith(e => this.ContinuedAction(e), context);
}
private void ContinuedAction(Task<StateObject> e)
{
this.ExecuteIfTaskIsNotFaulted(e, () =>
{
/* The action to execute
* I do stuff with e.Result
*/
});
}
}
There are two ways you can do this, dependent on the version of the language you are using.
C# 5.0 and above
You can use the
asyncandawaitkeywords to simplify a great deal of this for you.asyncandawaitwere introduced into the language to simplify using the Task Parallel Library, preventing you from having to useContinueWithand allowing you to continue to program in a top-down manner.Because of this, you can simply use a
try/catchblock to catch the exception, like so:Note that the method encapsulating the above must use have the
asynckeyword applied so you can useawait.C# 4.0 and below
You can handle exceptions using the
ContinueWithoverload that takes a value from theTaskContinuationOptionsenumeration, like so:The
OnlyOnFaultedmember of theTaskContinuationOptionsenumeration indicates that the continuation should only be executed if the antecedent task threw an exception.Of course, you can have more than one call to
ContinueWithoff the same antecedent, handling the non-exceptional case: