Asynchronous programming exception handling

In synchronous programming, where an exception is thrown whenever an error occurs, we can use try... Catch is used to catch exceptions, and uncaught exceptions are continuously passed up, forming a simple and unified error handling mechanism. But for asynchronous programming, exception handling has always been a hassle, so here's how to handle errors in asynchronous programmingCopy the code

Capture of a single exception

 public static async Task ThrowExcrptionAsync(int ms, string message)
        {
            await Task.Delay(ms);
            throw new Exception(message);
        }

 public static async Task Main(string[] args)
        {
            
            try
            {
               ThrowExcrptionAsync(2000, "first");
            }
            catch (Exception e)
            {
               Console.WriteLine(e.Message);
            }
            Console.ReadKey();
        }
Copy the code

If the above method is called and there is no waiting, the exception can be caught by placing the asynchronous method in a try/catch. For example, the ThrowExcrptionAsync method is called as above. The throw New Exception(message) sentence has not been executed, so the above code does not catch the Exception

Note: Asynchronous methods that return void do not wait because exceptions thrown from async void methods cannot be caught, so it is best for asynchronous methods to return a Task type. Handler methods or overridden base class methods are not subject to this rule

A better way to handle asynchronous method exceptions is to use the await keyword and place it in a try/catch statement, as in the following code trivia. When the ThrowExcrptionAsync method is called asynchronously, the main thread releases the thread, but the tower holds the reference to the task until it completes, at which point (2s later) the code in the matching catch block is called

 public static async Task Main(string[] args)
        {
            
            try
            {
            await   ThrowExcrptionAsync(2000, "first");
            }
            catch (Exception e)
            {
               Console.WriteLine(e.Message);
            }
            Console.ReadKey();
        }
Copy the code

Capture of multiple exceptions

What if two asynchronous methods are called and each method throws an exception? As followsCopy the code
 public static async Task Main(string[] args)
        {
            
            try
            {
            await   ThrowExcrptionAsync(2000, "first");
            await   ThrowExcrptionAsync(1000, "second");
            }
            catch (Exception e)
            {
               Console.WriteLine(e.Message);
            }
            Console.ReadKey();
        }
Copy the code

The first ThrowExcrptionAsync method is called, and 2s throws an exception message (containing the message first). After that, another ThrowExcrptionAsync method is called, and 1s later throws an exception. Because the first ThrowExcrptionAsync has already thrown an exception, the code block inside the try block does not proceed to call the second ThrowExcrptionAsync method. Instead, we go directly to the first exception in the catch block, but in real programming, that’s not what we think. We need both methods to execute regardless of the exception, rather than just jump out of one of them, so we use WhenAll method to wait for all methods to complete execution and then catch(define two tasks externally to accept the result of the method we want to execute).

 public static async Task Main(string[] args)
        {
            Task t1 = null;
            Task t2 = null;
            try
            {
                t1 = ThrowExcrptionAsync(2000, "first");
                t2 = ThrowExcrptionAsync(1000, "second");
                await Task.WhenAll(t1, t2);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            Console.ReadKey();
        }
Copy the code

At this point, we have both methods executed. Regardless of the internal error, let’s catch the error message in the two exceptions as follows

public static async Task Main(string[] args)
        {
            Task t1 = null;
            Task t2 = null;
            try
            {
                t1 = ThrowExcrptionAsync(2000, "first");
                t2 = ThrowExcrptionAsync(1000, "second");
                await Task.WhenAll(t1, t2);
            }
            catch (Exception e)
            {
                if (t1.IsFaulted)
                {
                    Console.WriteLine(t1.Exception.InnerException);
                }
                if (t2.IsFaulted)
                {
                    Console.WriteLine(t2.Exception.InnerException);
                }
                Console.WriteLine(e.Message);
            }
            Console.ReadKey();
        }
Copy the code
Here we use the IsFaulted property, which checks the state of the task to see if it is in error state and returns true if an exception occurs. You can access the information itself using exception.innerException in the Task class. Of course, we know the status of IsFaulted. There must be other business logic that can be done. A quick way to get exception information from the Task class is as follows:Copy the code
public static async Task Main(string[] args)
        {
            Task taskResult = null;
            try
            {
                var t1 = ThrowExcrptionAsync(2000, "first");
                var t2 = ThrowExcrptionAsync(1000, "second");
                await (taskResult = Task.WhenAll(t1, t2));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                foreach (var item in taskResult.Exception.InnerExceptions)
                {
                    Console.WriteLine(item.Message);
                }
            }
            Console.ReadKey();
        }
Copy the code
In fact, the method is similar to the above judgment state to obtain abnormal information, this method is mainly used in the log.Copy the code

If there is not very clear or there is a mistake, welcome to correct, if you like, you might as well click a “like” collection