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

如何在.NET Core带返回值的异步Task中捕获Task.Run抛出的异常

正确捕获Task.Run内部异常及代码优化方案

1. 核心逻辑说明

await关键字会自动解封Task运行过程中抛出的异常,你现有的try-catch包裹await代码的逻辑本身是可以捕获异常的,未生效的常见原因是调用该异步方法时没有加await,形成了"调用即忘"的逻辑,异常会被归类为未观察任务异常不会触发当前catch。
另外Google Sheets API原生提供异步执行方法,不需要用Task.Run包裹同步方法,属于多余操作,直接用原生异步API即可让逻辑更简洁、异常传递更直观。

2. 优化后可正常捕获异常的代码

public async Task<string> KullaniciBilgileriniAl()
{
    try
    {
        string range = "Kullanici Bilgileri";
        SpreadsheetsResource.ValuesResource.GetRequest request = this.service.Spreadsheets.Values.Get(spreadsheetId, range);
        // 直接使用官方提供的异步执行方法,无需额外封装Task.Run
        ValueRange response = await request.ExecuteAsync();
        IList<IList<object>> values = response.Values;
        string DataKullaniciAdi = (string)values[1][0];
        string DataSifre = (string)values[1][1];
        return DataKullaniciAdi + DataSifre;
    }
    // 可单独捕获网络相关异常针对性处理
    catch (HttpRequestException ex)
    {
        System.Diagnostics.Debug.WriteLine($"无网络连接,请求失败:{ex.Message}");
        return string.Empty;
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine($"请求异常:{ex}");
        return string.Empty;
    }
}

3. 调用侧注意事项

调用该异步方法时必须添加await关键字,才能让异常正常传递到调用栈:

// 错误写法:无await,异常无法被捕获
KullaniciBilgileriniAl();

// 正确写法:带await,异常可被正常捕获
string kullaniciBilgisi = await KullaniciBilgileriniAl();

如果是在GUI的事件回调中调用,可以用async void作为方法签名适配事件委托的返回值要求,示例如下:

private async void 数据加载按钮_Click(object sender, EventArgs e)
{
    try
    {
        var result = await KullaniciBilgileriniAl();
        // 后续UI更新逻辑
    }
    catch (Exception ex)
    {
        // 可在此处做UI层异常提示
        MessageBox.Show($"加载用户信息失败:{ex.Message}");
    }
}

4. 保留Task.Run写法的处理方案

如果因为特殊场景必须保留Task.Run包裹同步方法的写法,只需要确保调用侧加await,现有try-catch包裹await代码的逻辑就可以正常捕获所有内部抛出的异常,不需要额外修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:54:03