【问题标题】:Unobserved exception was rethrown despite awaiting the Task and catching Exception尽管等待任务并捕获异常,但未观察到的异常被重新抛出
【发布时间】:2016-01-19 14:03:04
【问题描述】:

我的代码可以捕获服务器调用引发的所有异常,如下所示:

    new public Task SaveAsync()
    {
        return ServerException.Wrap(base.SaveAsync);
    }

ServerException.Wrap 的样子:

    public static async Task<T> Wrap<T>(Func<Task<T>> func)
    {
        try
        {
            return await func();
        }
        catch (Exception ex)
        {
            // This is an internal error that shouldn't happen.
            throw new ServerException(ex);
        }
    }

    public static async Task Wrap(Func<Task> func)
    {
        await Wrap(async () =>
            {
                await func();
                return true;
            });
    }

然后我有一个调用 SaveAsync 的函数,如下所示:

        try
        {
            await problem.SaveAsync();
        }
        catch (ServerException ex)
        {
            Logger.LogException("Error saving problem.", ex);
        }

我有一些内部错误会生成一个异常,我在上面的行中捕获了该异常,然后记录如下:

2015-10-20 11:20:44.502 [第 99 行] 保存错误问题。 (例外: Exceptions.ServerException:---> System.ArgumentException:一个项目 已经添加了相同的密钥。在 System.ThrowHelper.ThrowArgumentException(ExceptionResource 资源) [0x00000] 在 /Users/builder/data/lanes/1977/2c66d2fe/source/mono/external/referencesource/mscorlib/system/throwhelper.cs:74

但是几秒钟后,我收到了一个未经处理的异常警告并被记录:

2015-10-20 11:21:16.352 警告:未处理的异常: System.AggregateException:未观察到任务的异常 通过等待任务或访问其异常属性。作为 结果,未观察到的异常被终结器重新抛出 线。 ---> System.ArgumentException:具有相同键的项目具有 已经添加。在 System.ThrowHelper.ThrowArgumentException (ExceptionResource 资源) [0x00000] in /Users/builder/data/lanes/1977/2c66d2fe/source/mono/external/referencesource/mscorlib/system/throwhelper.cs:74

为什么我得到第二个未观察到的异常,即使我正在捕获并处理第一个异常?这个异常似乎是我的 ServerException.Wrap 方法抛出的。

我正在使用 MonoTouch。

【问题讨论】:

  • 你确定这是所有相关代码吗?
  • 这是简化版。您还需要代码的其他什么部分?
  • 没有等待任务的部分 :) SaveAsync 看起来如何?
  • @KostubDeshmukh:请发布最少的可重现代码。这样我们也可以看到错误。
  • 我遇到了与 MonoTouch 类似的问题。你找到解决这个问题的方法了吗?

标签: c# .net exception xamarin.ios async-await


【解决方案1】:

您需要将异常显式设置为observed。

为此,您需要订阅TaskSchedulerUnobservedTaskException 事件,并将其显式设置为observed(对其调用SetObserved())。

看这里:

UnobservedTaskException being throw...

编辑: 当然你也可以只抓AggregateException,或者使用ContinueWith()观察并继续任务。

见官方文档底部:

Exception Handling (MSDN)

【讨论】:

  • 为什么一开始就应该不被观察?
猜你喜欢
  • 2013-10-10
  • 1970-01-01
  • 2011-12-14
  • 2012-02-29
  • 2016-11-25
  • 2020-02-13
  • 1970-01-01
  • 2017-03-23
  • 2012-06-08
相关资源
最近更新 更多