捕获调用异步方法C#的异常[重复]
Posted
技术标签:
【中文标题】捕获调用异步方法C#的异常[重复]【英文标题】:Catching exception of an invoke async method C# [duplicate] 【发布时间】:2021-02-09 05:22:41 【问题描述】:我正在尝试从需要调用的异步方法中获取异常,例如:
public async Task MyFirstMethod()
await Check(() => Test("test"));
private async Task<TResult> Check<TResult>(Func<TResult> function)
try
await Task.Run(() => function());
...
catch(Exception exception)
<<<Reach here>>>
private async Task<string> Test(string s)
await Task.Run(() => s.ToList());
throw new Exception("Exception Test");
如果 Test 方法不是异步的,并且我只是在 Check 方法中调用 function(),则此方法有效。 我做错了什么?
谢谢。
解决方案:改变
private async Task<TResult> Check<TResult>(Func<TResult> function)
转private async Task<TResult> Check<TResult>(Func<Task<TResult>> function)
【问题讨论】:
问题和动机有点不清楚。 我的直觉是你只想要private async Task<TResult> Check<TResult>(Func<Task<TResult>> function) return await function()
但是,在你澄清你想要做什么之前,所有的赌注都没有了
在将Task.Run()
与理论上的异步方法一起使用时需要非常小心,因为Task.Run()
有专门处理任务的重载不同于非异步场景。
我认为您会发现将Debug.WriteLine($"typeof(TResult): typeof(TResult).Name");
添加到您的Check<TResult>()
方法中非常有启发性。我敢打赌,您不会期望 TResult
成为 Task<string>
,但确实如此。这意味着您需要等待 result 值本身(即表达式 await Check(...)
返回的值)来观察异常。在您这样做之前,异常仍然包含在它发生的任务中。
换句话说,将参数更改为Check
为Func<Task<TResult>>
而不是Func<TResult>
。
【参考方案1】:
发生这种情况是因为您没有在引发异常的地方(在相同的上下文中)捕获异常。
试试这个
private async Task<TResult> Check<TResult>(Func<TResult> function)
await Task.Run(() =>
try
function();
catch(Exception exception)
// do whatever
);
【讨论】:
function
是异步的。那个 try-catch 就像它不存在一样有用。以上是关于捕获调用异步方法C#的异常[重复]的主要内容,如果未能解决你的问题,请参考以下文章