C# 多个异步方法的异常处理

共 1388字,需浏览 3分钟

 ·

2022-03-16 10:10




如果调用两个异步方法,每个都会抛出异常,该如何处理呢 ? 在下面的示例中,第一个 ThrowAfter 方法被调用,2s 后抛出异常(含消息 first)。该方法结束后,另一个 ThrowAfter 方法也被调用,1s 后也抛出异常。事实并非如此,因为对第一个 ThrowAfter 方法的调用已经抛出了异常,try 块内的代码没有继续调用第二个 ThrowAfter 方法,而是在 catch 块内对第一个异常进行处理。

代码如下:


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  {ex.Message}");  }}


现在,并行调用这两个 ThrowAfter 方法。第一个 ThrowAfter 方法 2s 后抛出异常,1s 后第二个 ThrowAfter 方法也抛出异常。使用 Task.WhenAll,不管任务是否抛出异常,都会等到两个任务完成。因此,等待 2s 后, Task.WhenAll 结束,异常被 catch 语句捕获到。但是,只能看见传递给 WhenAll 方法的第一个任务的异常信息,没有显示先抛出异常的任务(第二个任务),但该任务也在列表中:

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


有一种方式可以获取所有任务的异常信息,就是在 try 块外声明任务变量 t1 和t2,使它们可以在 catch 块内访问。在这里,可以使用 IsFaulted 属性检查任务的状态,以确认它们是否为出错状态。若出现异常,IsFaulted 属性会返回true。可以使用 Task 类的 Exception.InnerException 访问异常信息本身。


浏览 64
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报