Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Task Exception Management c#

I run a solution that contains 2 projects: the app and the sdk.

Through the app I create an instance of the sdk so the app can start. The problem is that when I get an Exception in a part of code running inside of a Task, no Unhandled Exception is thrown so my app keeps running and doesn't realise an unexpected is happening in the SDK.

I am registered to AppDomain.CurrentDomain.UnhandledException's event in the App and SDK, but as said when the Exception is thrown in a Task, the event handler isn't called.

Is there something that I am missing?

like image 320
user3009804 Avatar asked Dec 20 '22 07:12

user3009804


2 Answers

Both answers are somewhat (but not fully) complete.

Asynchronous

The best way to handle a faulted task is to asynchronously wait for it to complete using await. This will rethrow the original stored exception:

try
{
    await task;
}
catch (Exception e)
{
    // handle exception
}

Synchronous

If you can't do that (or don't want to) you can also use task.Wait() which waits synchronously and throws an AggregateException containing the original exception in InnerExceptions or register a continuation that handles it (i.e. task.ContinueWith(t => // handle exception))

UnobservedTaskException

In .Net 4.0 an unobserved Task exception would bring down the entire process. The TaskScheduler.UnobservedTaskException event was the last option to handle the exception before the crash (very similar to the case of UnhandledException). In .Net 4.5 this type of exception no longer crashes the app, but the event is still raised.

If you want to crash the app in this case (and I doubt you do) you can set <ThrowUnobservedTaskExceptions enabled="true"/> as Yuval pointed out. You can instead use the event itself to handle the exception which isn't optimal for 2 reasons:

  1. .Net decides your task's exception was unobserved only when the task is garbage collected which could happen anytime (or never, if you don't release all references to it). Until then you may still handle the exception yourself, so it isn't yet unobserved.
  2. You get the exception, but not the task, and it can be difficult to know the real origin of the problem without it.

Conclusion

Make sure to await your tasks to handle exceptions as they occur. Also use UnobservedTaskException as a catch all in case you missed a task.

like image 57
i3arnon Avatar answered Jan 04 '23 20:01

i3arnon


When a Task throws an unhandled exception, its execution is terminated and you can check for IsFaulted and Exception properties on the original Task object.

More info about those properties here and here, and there's an article devoted to exception handling in Tasks on the MSDN

You also have the UnobservedTaskException event on TaskScheduler. I've never used it myself, but reading about it, it should be similar to the UnhandledException event on AppDomain. Check it on MSDN

like image 38
Jcl Avatar answered Jan 04 '23 18:01

Jcl