猿问

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

在我使用 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 上使用的那样在一个地方捕获类中的所有异常?也许我可以用某些属性标记所需的方法?


哔哔one
浏览 204回答 1
1回答

墨色风雨

首先,我建议您不要.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{&nbsp; &nbsp; var task = Task.Run(async () => await this.Object(User));&nbsp;&nbsp; &nbsp; return task.Result.Content;}catch(AggregateException ex){&nbsp; &nbsp; throw ex.InnerException;}类似于:return RunAsync(() => this.Object(User));private T RunAsync<T>(Func<Task<T>> func){&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; try&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var task = Task.Run(func);&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; return task.Result;&nbsp; &nbsp; }&nbsp; &nbsp; catch(AggregateException ex)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; throw ex.InnerException;&nbsp; &nbsp; }}编辑:我刚刚意识到还有另一种方式(参见http://blog.stephencleary.com/2014/12/a-tour-of-task-part-6-results.html),它稍微有点“hacky”,因为感觉更隐蔽,但这个:var task = Task.Run(async () => await this.Object(User));&nbsp;return task.GetAwaiter().GetResult().Content;在.GetAwaiter().GetResult()将同步等待Task(按.Result),但不会换在任何抛出的异常AggregateException-这似乎是你的愿望。
随时随地看视频慕课网APP
我要回答