Introduced in C# 5 async/await keywords significantly simplify asynchronous code and improve code readability and maintainability. However, when it comes to exception handling, it becomes a bit trickier.

Let’s consider the following example:


static void Main(string[] args)
{
    try
    {
        AsyncMethod();
    }
    catch
    {
        Console.WriteLine("Exception in Main");
    }

    Console.ReadLine();
}

private async static void AsyncMethod()
{
    throw new NotImplementedException();
}

When executed, instead of displaying “Exception in Main” message, this program crashes. Similar to this console application, all exceptions raised from async void methods crash Windows 8 apps too.

In console and desktop programs unhandled exceptions can be intercepted using AppDomain.UnhandledException event. Only intercepted, for example for logging - it doesn’t prevent crash of the program. In Windows 8 apps even interception is not possible because AppDomain is not part of .NET profile for Windows Store apps.

Windows 8.1 changes the way the async-related exceptions are handled. Now it is possible to catch exception raised from async void method by handling Application.UnhandledException event:


sealed partial class MyApp : Application
{
    public MyApp()
    {
        this.InitializeComponent();

        UnhandledException += Application_UnhandledException;

    }

    private void Application_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        e.Handled = true;
        // ...
    }
}

With UnhandledException event it is possible to not only log exception but also prevent process termination (e.Handled = true).

The following example demonstrate code that will behave differently in Windows 8 and Windows 8.1:


private async void Button_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
    throw new NotImplementedException();
}

In Windows 8 it will raise exception and terminate process, without possibility to catch it using Application.UnhandledException event. In Windows 8.1 Application.UnhandledException event will be fired in case of such exception.

blog comments powered by Disqus