Exception Handling in C# Asynchronous Programming

Introduction 

Welcome to the Asynchronous Programming series. In the previous three articles, we explained the async and await keywords and the return type of asynchronous methods and tasks. You can read them here.

  1. Asynchronous programming in C# 5.0: Part-1: Understand async and await
  2. Asynchronous Programming in C# 5.0 Part 2: Return Type of Asynchronous Method
  3. Asynchronous Programming in C# 5.0 Part 3: Understand Task in Asynchronous programming.

In this article, we will explain Exception Handling in asynchronous programming. I hope you are experienced with Exception Handling in C#, but you may not know how to implement Exception Handling in asynchronous programming. Let's see how to implement try-catch blocks in asynchronous programming. Have a look at the following code.

Traditional Try-Catch in Asynchronous programming

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading;  
using System.Threading.Tasks;  
namespace Asynchronious  
{  
    class Test  
    {  
        public Task ShowAsync()  
        {  
            return Task.Run(()=>{  
                Task.Delay(2000);  
                throw new Exception("My Own Exception");  
            });  
        }  
        public async void Call()  
        {  
            await ShowAsync();  
        }  
    }   
    class Program  
    {  
        public static void Main(String [] args)  
        {  
            Test t = new Test();  
            try  
            {  
                t.Call();  
            }  
            catch (Exception ex)  
            {  
                Console.WriteLine(ex.Message);  
            }  
            Console.ReadLine();  
        }  
    }  
}

We have declared a Test class with an asynchronous function, ShowAsync(), that will throw an exception. One more function (Call) will call the ShowAsync() function. From the Main() function we are calling the Call() function wrapping try catch blocks. We hope that in the catch block, the exception will be handled. Have a look at the following output:

image1.gif

Oh! The catch is not handling an exception? Why? The reason is that it's asynchronous in nature. As we know, in asynchronous programming, control does not wait for the function's result and it executes the next line. So when the function throws an exception, at that moment the program control is out of the try-catch block. This is why it exists.

Implement try-catch within the function

Let's implement a try-catch block within an asynchronous function. This is the solution to catch exceptions in asynchronous methods. Have a look at the following code. If you look closely inside the ShowAsync() function, then you will find we have implemented a try-catch within Task.run(). Within Task.run(), all processes are executed synchronously (in our example). So, if there is an exception, then it will be caught by the Exception Handling block.

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading;  
using System.Threading.Tasks;  
namespace Asynchronious  
{  
    class Test  
    {  
        public Task ShowAsync()  
        {  
                return Task.Run(() =>  
                {  
                    try  
                    {  
                        Task.Delay(2000);  
                        throw new Exception("My Own Exception");  
                    }  
                    catch (Exception ex)  
                    {  
                        Console.WriteLine(ex.Message);  
                        return null;  
                    }  
                });  
        }  
        public async void Call()  
        {  
            try  
            {  
                await ShowAsync();  
            }  
            catch (Exception ex)  
            {  
                Console.WriteLine(ex.Message);  
            }  
        }  
    }   
    class Program  
    {  
        public static void Main(String [] args)  
        {  
            Test t = new Test();  
            t.Call();  
            Console.ReadLine();  
        }  
    }  
}

Now, you may wonder: We have implemented a try-catch block within Task and it's fine, but what need is there for implementing a try-catch within the Call() function? The reason is because when an asynchronous function fails to execute a Task, it throws a Task Cancelled exception. We need to implement a mechanism to catch this exception.

Here is the output screen:

image3.gif

We see that now the Exception Handling block is capable of catching the exception.

Now the question is: is it possible to wrap a try-catch block over an asynchronous function as is done for traditional synchronous functions? The answer is that we can, but with a limitation. What is the limitation? The exception should occur outside of the Task process statement. Then the Exception Handling block can catch the exception. Let's see the following example:

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading;  
using System.Threading.Tasks;  
namespace Asynchronious  
{  
    class Test  
    {  
        public Task ShowAsync()  
        {  
            throw new Exception("My Own Exception");  
            return Task.Run(() =>  
                {  
                    Task.Delay(2000);  
                });              
        }  
        public async void Call()  
        {  
            try  
            {  
               await ShowAsync();  
            }  
            catch (Exception ex)  
            {  
                Console.WriteLine(ex.Message);  
            }  
        }  
    }   
    class Program  
    {  
        public static void Main(String [] args)  
        {  
            Test t = new Test();  
            t.Call();  
            Console.ReadLine();  
        }  
    }  
} 

Here the exception occurs outside of the Task, now the exception is caught by the try catch block from the calling location. Here is the sample output:

image4.gif

Conclusion

This article has explained Exception Handling in asynchronous programming. I hope you have understood it. In the next article, I would like to discuss a few more real-world examples of asynchronous programming.

Next Article >> Asynchronous Programming in C# 5.0: Part Five: Access Data Sing Asynchronous Function


Similar Articles