【问题标题】:Catching exception of an invoke async method C# [duplicate]捕获调用异步方法C#的异常[重复]
【发布时间】: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&lt;TResult&gt; Check&lt;TResult&gt;(Func&lt;TResult&gt; function)private async Task&lt;TResult&gt; Check&lt;TResult&gt;(Func&lt;Task&lt;TResult&gt;&gt; function)

【问题讨论】:

  • 问题和动机有点不清楚。
  • 我的直觉是你只想要private async Task&lt;TResult&gt; Check&lt;TResult&gt;(Func&lt;Task&lt;TResult&gt;&gt; function) {return await function()} 但是,在你澄清你想要做什么之前,所有的赌注都没有了
  • 在将Task.Run() 与理论上的异步方法一起使用时需要非常小心,因为Task.Run() 有专门处理任务的重载不同于非异步场景。
  • 我认为您会发现将Debug.WriteLine($"typeof(TResult): {typeof(TResult).Name}"); 添加到您的Check&lt;TResult&gt;() 方法中非常有启发性。我敢打赌,您不会期望 TResult 成为 Task&lt;string&gt;,但确实如此。这意味着您需要等待 result 值本身(即表达式 await Check(...) 返回的值)来观察异常。在您这样做之前,异常仍然包含在它发生的任务中。
  • 换句话说,将参数更改为CheckFunc&lt;Task&lt;TResult&gt;&gt; 而不是Func&lt;TResult&gt;

标签: c# .net asynchronous exception


【解决方案1】:

发生这种情况是因为您没有在引发异常的地方(在相同的上下文中)捕获异常。

试试这个

private async Task<TResult> Check<TResult>(Func<TResult> function)
{
        await Task.Run(() => {
           try 
           {
              function();
           }
           catch(Exception exception)
           {
              // do whatever
           }
        });
}

【讨论】:

  • function 是异步的。那个 try-catch 就像它不存在一样有用。
猜你喜欢
  • 2015-04-14
  • 1970-01-01
  • 2015-04-22
  • 1970-01-01
  • 2011-07-19
  • 2021-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多