为了账号安全,请及时绑定邮箱和手机立即绑定

类的异常过滤器有许多不同的方法

类的异常过滤器有许多不同的方法

C#
哔哔one 2021-11-28 16:21:23
在我使用 webApi 的客户端应用程序中,我有很多方法可以像这样异步调用 webApi:var task = Task.Run(async () => await this.SaveObject(User)); return task.Result.Content;如果保存的对象有问题,异步函数可能会抛出异常。在这种情况下,我的异常将根据它的类型在客户端上处理。问题是当异步任务抛出异常时,task.Result.Content埋在System.AggregateException.现在我是这样处理的:        try        {            var task = Task.Run(async () => await this.saveObject(User)); return task.Result.Content;        }        catch(AggregateException ex)        {            throw ex.InnerException;        }我有太多方法以同样的方式做到这一点。我想知道是否有办法避免在每种方法中使用 try/catch 块。也许有一种异常过滤机制,有点像在 webApi 上使用的那样在一个地方捕获类中的所有异常?也许我可以用某些属性标记所需的方法?
查看完整描述

1 回答

?
墨色风雨

TA贡献1853条经验 获得超6个赞

首先,我建议您不要.Result在Task. 请参阅https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html或https://montemagno.com/c-sharp-developers-stop-calling-dot-result/。


如果你按照上面的建议和await一个Task一个中try块,它会抛出实际的异常,而不是一个AggregateException,所以你也许能完全避免你重新抛出的代码。


否则,如果你真的想坚持你的.Result代码,你可以编写一个通用的包装方法来为你处理常见的错误:


try

{

    var task = Task.Run(async () => await this.Object(User)); 

    return task.Result.Content;

}

catch(AggregateException ex)

{

    throw ex.InnerException;

}

类似于:


return RunAsync(() => this.Object(User));



private T RunAsync<T>(Func<Task<T>> func)

{    

    try

    {

        var task = Task.Run(func); 

        return task.Result;

    }

    catch(AggregateException ex)

    {

        throw ex.InnerException;

    }

}

编辑:我刚刚意识到还有另一种方式(参见http://blog.stephencleary.com/2014/12/a-tour-of-task-part-6-results.html),它稍微有点“hacky”,因为感觉更隐蔽,但这个:


var task = Task.Run(async () => await this.Object(User)); 

return task.GetAwaiter().GetResult().Content;

在.GetAwaiter().GetResult()将同步等待Task(按.Result),但不会换在任何抛出的异常AggregateException-这似乎是你的愿望。


查看完整回答
反对 回复 2021-11-28
  • 1 回答
  • 0 关注
  • 203 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信