异步编程错误处理 ERROR HANDLING

Chapter 16, "Errors and Exceptions," provides detailed coverage of errors and exception handling. However, in the context of asynchronous methods, you should be aware of some special handling of errors.

Let‘s start with a simple method that throws an exception after a delay (code file ErrorHandling/Program.cs):


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

If you call the asynchronous method without awaiting it, you can put the asynchronous method within a try/catch block—and the exception will not be caught. That‘s because the method DontHandle has already completed before the exception from ThrowAfter is thrown. You need to await the ThrowAfter method, as shown in the following example:


    private static void DontHandle()
    {
      try
      {
        ThrowAfter(200, "first");
        // exception is not caught because this method is finished
        // before the exception is thrown
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
      }
    }
  Warning 
Asynchronous methods that return void cannot be awaited. The issue with this is that exceptions that are thrown from async void methods cannot be caught. That‘s why it is best to return a Task type from an asynchronous method. Handler methods or overridden base methods are exempted from this rule.

Handling Exceptions with Asynchronous Methods

A good way to deal with exceptions from asynchronous methods is to use await and put a try/catch statement around it, as shown in the following code snippet. The HandleOneError method releases the thread after calling the ThrowAfter method asynchronously, but it keeps the Task referenced to continue as soon as the task is completed. When that happens (which in this case is when the exception is thrown after two seconds), the catch matches and the code within the catch block is invoked:


    private static async void HandleOneError()
    {
      try
      {
        await ThrowAfter(2000, "first");
      }
      catch (Exception ex)
      {
        Console.WriteLine("handled {0}", ex.Message);
      }
    }

Exceptions with Multiple Asynchronous Methods

What if two asynchronous methods are invoked that each throw exceptions? In the following example, first the ThrowAfter method is invoked, which throws an exception with the message first after two seconds. After this method is completed, the ThrowAfter method is invoked, throwing an exception after one second. Because the first call to ThrowAfter already throws an exception, the code within the try block does not continue to invoke the second method, instead landing within the catch block to deal with the first exception:


    private static async void StartTwoTasks()
    {
      try
      {
        await ThrowAfter(2000, "first");
        await ThrowAfter(1000, "second"); // the second call is not invoked
                                          // because the first method throws
                                          // an exception
      }
      catch (Exception ex)
      {
        Console.WriteLine("handled {0}", ex.Message);
      }
    }

Now let‘s start the two calls to ThrowAfter in parallel. The first method throws an exception after two seconds, the second one after one second. With Task.WhenAll you wait until both tasks are completed, whether an exception is thrown or not. Therefore, after a wait of about two seconds, Task.WhenAll is completed, and the exception is caught with the catch statement. However, you will only see the exception information from the first task that is passed to the WhenAll method. It‘s not the task that threw the exception first (which is the second task), but the first task in the list:


    private async static void StartTwoTasksParallel()
    {
      try
      {
        Task t1 = ThrowAfter(2000, "first");
        Task t2 = ThrowAfter(1000, "second");
        await Task.WhenAll(t1, t2);
      }
      catch (Exception ex)
      {
        // just display the exception information of the first task
        // that is awaited within WhenAll
        Console.WriteLine("handled {0}", ex.Message);
      }
    }

One way to get the exception information from all tasks is to declare the task variables t1 and t2 outside of the try block, so they can be accessed from within the catch block. Here you can check the status of the task to determine whether they are in a faulted state with the IsFaulted property. In case of an exception, the IsFaulted property returns true. The exception information itself can be accessed by using Exception.InnerException of the Task class. Another, and usually better, way to retrieve exception information from all tasks is demonstrated next.

Using AggregateException Information

To get the exception information from all failing tasks, the result from Task.WhenAll can be written to a Task variable. This task is then awaited until all tasks are completed. Otherwise the exception would still be missed. As described in the last section, with the catch statement just the exception of the first task can be retrieved. However, now you have access to the Exception property of the outer task. The Exception property is of type AggregateException. This exception type defines the property InnerExceptions (not only InnerException), which contains a list of all the exceptions from the awaited for. Now you can easily iterate through all the exceptions:


    private static async void ShowAggregatedException()
    {
      Task taskResult = null;
      try
      {
        Task t1 = ThrowAfter(2000, "first");
        Task t2 = ThrowAfter(1000, "second");
        await (taskResult = Task.WhenAll(t1, t2));
      }
      catch (Exception ex)
      {
        Console.WriteLine("handled {0}", ex.Message);
        foreach (var ex1 in taskResult.Exception.InnerExceptions)
        {
          Console.WriteLine("inner exception {0}", ex1.Message);
        }
      }
    }
时间: 2024-10-05 03:56:54

异步编程错误处理 ERROR HANDLING的相关文章

[译]Javascript中的错误信息处理(Error handling)

本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU&list=PL6n9fhu94yhUA99nOsJkKXBqokT3MBK0b 在Javascript中使用try/catch/finally来处理runtime的错误.这些runtime错误被称为exceptions.各种各样的原因都可能导致exception.比如,使用没有申明的变量或者方法都可

转:C++编程隐蔽错误:error C2533: 构造函数不能有返回类型

C++编程隐蔽错误:error C2533: 构造函数不能有返回类型 今天在编写类的时候,出现的错误. 提示一个类的构造函数不能够有返回类型.在cpp文件里,该构造函数定义处并没有返回类型.在头文件里,构造函数原型也无返回类型. 这就奇怪了,凭借多年的编程经验,似乎有一些似曾相识的灵感(以前似乎犯过同一个错误) 然后在头文件的末尾处,发现一个类的结尾处并没写上分号.(小心小心再小心!!!) 看来在把头文件包含到Cpp文件里时,误把没有加上分号的类当成了提示错误的构造函数的返回类型. 特此注意.

Error Handling 错误处理

This tutorials aims to teach you how to create an error handler for your programs to deal with the clean-up operation when something in the code goes wrong. by:http://lee-mac.com/errorhandling.html What can go Wrong? Errors can arise in many forms: f

Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十二)之Error Handling with Exceptions

The ideal time to catch an error is at compile time, before you even try to run the program. However, not all errors can be detected at compile time. To create a robust system, each component must be robust. By providing a consistent error-reporting

使用异步编程

转发至:http://www.ituring.com.cn/article/130823 导言 现代的应用程序面临着诸多的挑战,如何构建具有可伸缩性和高性能的应用成为越来越多软件开发者思考的问题.随着应用规模的不断增大,业务复杂性的增长以及实时处理需求的增加,开发者不断尝试榨取硬件资源.优化. 在不断的探索中,出现了很多简化场景的工具,比如提供可伸缩计算资源的Amazon S3.Windows Azure,针对大数据的数据挖掘工具MapReduce,各种CDN服务,云存储服务等等.还有很多的工程

探索Javascript异步编程

异步编程带来的问题在客户端Javascript中并不明显,但随着服务器端Javascript越来越广的被使用,大量的异步IO操作使得该问题变得明显.许多不同的方法都可以解决这个问题,本文讨论了一些方法,但并不深入.大家需要根据自己的情况选择一个适于自己的方法. 笔者在之前的一片博客中简单的讨论了Python和Javascript的异同,其实作为一种编程语言Javascript的异步编程是一个非常值得讨论的有趣话题. JavaScript 异步编程简介 回调函数和异步执行 所谓的异步指的是函数的调

探索Javascript 异步编程

在我们日常编码中,需要异步的场景很多,比如读取文件内容.获取远程数据.发送数据到服务端等.因为浏览器环境里Javascript是单线程的,所以异步编程在前端领域尤为重要. 异步的概念 所谓异步,是指当一个过程调用发出后,调用者不能立刻得到结果.实际处理这个调用的过程在完成后,通过状态.通知或者回调来通知调用者. 比如我们写这篇文字时点击发布按钮,我们并不能马上得到文章发布成功或者失败.等待服务器处理,这段时间我们可以做其他的事情,当服务器处理完成后,通知我们是否发布成功. 所谓同步,是指当一个过

C#的多线程——使用async和await来完成异步编程(Asynchronous Programming with async and await)

https://msdn.microsoft.com/zh-cn/library/mt674882.aspx 侵删 更新于:2015年6月20日 欲获得最新的Visual Studio 2017 RC文档,参考Visual Studio 2017 RC Documentation. 使用异步编程,你可以避免性能瓶颈和提升总体相应效率.然而,传统的异步方法代码的编写方式比较复杂,导致它很难编写,调试和维护. Visual Studio 2012引入了一个简单的异步编程的方法,依赖.NET Fram

JavaScript异步编程设计快速响应的网络应用

JavaScript已然成为了多媒体.多任务.多内核网络世界中的一种单线程语言.其利用事件模型处理异步触发任务的行为成就了JavaScript作为开发语言的利器.如何深入理解和掌握JavaScript异步编程变得尤为重要!!!<JavaScript异步编程设计快速响应的网络应用>提供了一些方法和灵感. 一.深入理解JavaScript事件 1. 事件的调度 JavaScript事件处理器在线程空闲之前不会运行(空闲时运行). var start = new Date(); setTimeout