Asynchronous Programming in C# 5.0 Part 6: 3 Best Practices in Asynchronous Programming

Welcome to the Asynchronous Programming in C# 5.0 article series. If you are an old reader then you probably know what was explained in this series so far. If you are new then please find the previous articles in the following links.  

  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.
  4. Asynchronous Programming in C# 5.0 Part 4: Exception Handling in Asynchronous Programming
  5. Asynchronous Programming in C # 5.0 Parts 5: Access data using asynchronous function.

As the title suggests, in this article we will explain a few best practices in Asynchronous Programming. Let's try to understand them one by one with an example.

1. Avoid return Void from asynchronous function

We know that, there are three possible return types from an asynchronous function, they are:

  • Void
  • Task
  • Task<T>

It is recommended not to return void from any asynchronous function. Now the question is, why? Let's explain. We will implement one asynchronous function with return type void. Have a look at the following code. We have defined Asyncfun() with void return type.

Asynchronous-programming-1.jpg

Now, from the Call() function we are trying to call this asynchronous function. And we are seeing that the compiler is saying that we cannot use the await keyword to call an asynchronous function that returns void. So, we need to return either Task or Task<T>.
Then, again question is, why do asynchronous functions support void? Is there some use of that?  Yes, the use is there. Use void when you define an event handler with async qualifier, as in the following.

Asynchronous-programming-2.jpg

Let's see, we have qualify Button1_Click() event as asynchronous and it's return type is void.

2. Implement exception handling block in proper place

Be careful when you implement a try-catch block in an asynchronous function. Don't treat an asynchronous function as normal. Have a look at Following code.

using System;

using System.Runtime.CompilerServices;

using System.Threading;

using System.Threading.Tasks;

 

namespace Asynchronious

{

        class Program

        {

 

            public static async Task Asyncfun()

            {

                throw new Exception("This is my exception");

            }

            public static async void Call()

            {

              await Asyncfun();  

            }

            public static void Main(String[] args)

            {

                try

                {

                    Call();

                }

                catch (Exception ex)

                {

                    Console.WriteLine(ex.Message);

                }

 

                Console.ReadLine();

            }

        }

}

When we run this code we get the following error.

Asynchronous-programming-3.jpg

So, the try-catch block fails to handle the exception. Now, the question is where to implement the try-catch block? Implement the try-catch block within the asynchronous function.
 

using System;

using System.Runtime.CompilerServices;

using System.Threading;

using System.Threading.Tasks;

 

namespace Asynchronious

{

    class Program

    {

        public static async Task<String> Asyncfun()

        {

            try

            {

                //Some business code is here

                throw new Exception("This is my exception");

            }

            catch (Exception ex)

            {

                Console.WriteLine(ex.Message);

                return null;

            }

        }

        public static async void Call()

        {

            await Asyncfun();

        }

        public static void Main(String[] args)

        {

             Call();

             Console.ReadLine();

        }

    }

}


In this code we wrapped the function of the asynchronous method with a try-catch statement.  Now we can handle exceptions thrown by the asynchronous function.

Asynchronous-programming-4.jpg

3. Don't implement asynchronous just because you can

Then why do we need to learn asynchronous programming? Hold on dear; let me explain why.  Asynchronous functions are for a time consuming process. The reason is when we call an asynchronous function many operations happen behind the scenes. What are the operations?

When we call a function asynchronously the operation between threads are changed, executes context switching and copies the state of the current thread in variable and many more, and to do al that it takes little (realy little?) time.

Let's implement two versions (one asynchronous and one synchronous) of the same function and try to get the execution times.
 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.CompilerServices;

using System.Text;

using System.Threading;

using System.Threading.Tasks;

using System.Diagnostics;

 

namespace Asynchronious

{

        class Program

        {

            public static async Task<String> Asyncfun()

            {

                    //This is dummy return   

                    return "Hello World";

            }

            public static async void CallAsync()

            {

                    await Asyncfun();

            }

            public static string NonAsync()

            {

                //This is dummy return 

                return "Hello World";

            }

            public static void CallNonAsync()

            {

                NonAsync();

            }

            public static void Main(String[] args)

            {

                Stopwatch sw = new Stopwatch();

                sw.Start();

                CallAsync();

                Console.WriteLine("Asynchronous Call:- " + sw.ElapsedTicks);

                sw.Reset();

                sw.Start();

                CallNonAsync();               

                Console.WriteLine("Synchronous Call:- " + sw.ElapsedTicks);

                sw.Stop();

                Console.ReadLine();

            }

      }

}


Here is sample output.

Asynchronous-programming-5.jpg

Hmm, the asynchronous function does take much and much and much longer time than a normal function. Hmm, if you don't believe this output, I will suggest you to run this code in your system (you may even first call the synchronous function) and the result will not differ much.

Ok, understood, then where do we need to implement the asynchronous function?  This is already explained in previous articles, please visit them.

Just keep in mind, the asynchronous scenario is suitable when we want to call another thread (non .NET net) from our current .NET Thread.

Conclusion

This article has explain a few best practices for asynchronous programming. Hope you have enjoyed them. Keep learning.
 

<< Previous article


Similar Articles