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

本文探讨了在异步编程中如何处理多个可能会抛出异常的任务。当两个异步方法并行调用时,即使其中一个抛出异常,Task.WhenAll仍会等待所有任务完成。在使用Task.WhenAll时,catch块只会捕获到第一个抛出异常的任务信息。为获取所有任务的异常信息,可以预先声明任务并在catch块内检查它们的IsFaulted属性和Exception.InnerException。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

a4a511aa730e4724c6584d05be23f7f5.png

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

e6a38e11e3c88c930f5c9f4e61f4daf3.png

代码如下:

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}");
  }
}

058d3de4f571b1a77fe1312c2b2735db.png

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

134c0b64decac815cf23af210a201a8a.png

代码如下:

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}");
  }
}

c8131c1bf1017f9073aef5ee89654bd8.png

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

70dedafab4cbfdf6556a6879478bd329.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值