You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中批量捕获Task的异常?

问题分析与解决方案

核心问题拆解

  1. 第一个写法的异常捕获失效:CreateBooking是async Task方法,直接调用而不使用await时,异常会被封装在返回的Task对象中,不会立即抛出,外层的try/catch自然无法捕获。
  2. 第二个写法的两个问题:
    • 复用createBookingModel引用:所有任务会共享该对象的最后一次修改值,导致业务逻辑错误;
    • Task.WaitAll是同步阻塞调用,不符合异步编程最佳实践,且若未正确遍历AggregateException.InnerExceptions,会遗漏部分异常。

推荐解决方案:异步并行执行+全异常捕获

var tasks = new List<Task>();
foreach (DateTime day in EachDay(originalStartDate, originalEndDate))
{
    // 每次循环创建独立的模型实例,避免引用共享导致参数串值
    var bookingModel = new CreateBookingModel
    {
        // 复制原模型的其他属性
        Name = createBookingModel.Name,
        CustomerId = createBookingModel.CustomerId,
        StartDate = day,
        EndDate = day
    };
    tasks.Add(CreateBooking(bookingModel));
}

// 异步等待所有任务完成,无同步阻塞
await Task.WhenAll(tasks);

// 遍历所有任务,收集并处理全部异常
foreach (var task in tasks)
{
    if (task.IsFaulted)
    {
        foreach (var ex in task.Exception.InnerExceptions)
        {
            if (ex is ExternalBookingException)
            {
                raiseToTeams(ex, "Creation error");
            }
            else
            {
                // 可根据需求处理其他类型异常,比如记录日志
                // raiseToTeams(ex, "Unexpected booking error");
            }
        }
    }
}

备选方案:串行执行+逐个处理异常

如果不需要并行执行,可采用串行方式逐个处理任务,异常捕获更直观:

foreach (DateTime day in EachDay(originalStartDate, originalEndDate))
{
    var bookingModel = new CreateBookingModel
    {
        // 复制原模型属性
        Name = createBookingModel.Name,
        StartDate = day,
        EndDate = day
    };

    try
    {
        await CreateBooking(bookingModel);
    }
    catch (ExternalBookingException ex)
    {
        raiseToTeams(ex, "Creation error");
    }
    catch (Exception ex)
    {
        // 处理其他未预期异常
        // raiseToTeams(ex, "Unexpected error");
    }
}

关键注意事项

  • 引用类型参数隔离:必须为每个任务创建独立的CreateBookingModel实例,否则所有任务会共享同一个对象的最终状态,导致日期参数错误。
  • 异步等待优先:用await Task.WhenAll替代Task.WaitAll,避免阻塞线程,符合.NET异步编程模型。
  • 全异常收集:通过遍历每个任务的Exception.InnerExceptions,可以捕获所有任务抛出的异常,不会遗漏。

内容的提问来源于stack exchange,提问作者Adrien Ruffie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 06:30:37