【问题标题】:Why am I not catching an exception in my async application? [duplicate]为什么我没有在我的异步应用程序中捕获异常? [复制]
【发布时间】:2020-06-02 20:41:00
【问题描述】:

我一直在阅读,例如这里 (Catch an exception thrown by an async void method),我认为 async Task 方法的行为是:

  1. 您可以在使用awaitTask.Wait 时照常尝试/捕获它们,例如try{ await X();}catch(Exception SqlException e){...}
  2. 如果你让它“冒泡”,你会得到AggregateException

但我发现我的应用程序只是终止而没有中断异常。我的代码如下:

    internal async Task RunAsync()
    {
        var tasks = monitors.Select((p) => p.Value.MonitorAsync()).ToList();
        await Task.WhenAny(tasks);
        Console.WriteLine("ONE");
    }

    public static async Task Main(string[] args)
    {
        var app = new App();
        try
        {
            await app.RunAsync();
            Console.WriteLine("TWO");
        }
        catch(Exception e)
        {
            Console.WriteLine(e);
        }
    }

在“ONE”和“TWO”上设置断点我可以看到tasks 至少有一个Task 的状态为Faulted,t 的状态为RanToCompletion。所以故障状态丢失,没有异常。

显然我遗漏了一些明显的东西,我应该做些什么不同的事情?

顺便说一句WhenAny 用于检测异常终止,这些任务应该只因失败而退出。这更像是一个了解捕获异常的测试平台。

【问题讨论】:

    标签: c# .net task-parallel-library


    【解决方案1】:

    这是因为WhenAny。请查看documentation

    返回的任务将在任何提供的任务完成时完成 完全的。返回的任务总是以 RanToCompletion 结束 将其 Result 设置为要完成的第一个任务的状态。 这是真的 即使要完成的第一个任务以 Cancelled 或 Faulted 结束 状态(强调我的)

    这意味着如果任何任务出错,WhenAny 将不会引发异常。

    这与WhenAll相反,如果它等待的任何任务出现未处理异常的错误,则会引发异常。

    【讨论】:

    • 谢谢,仔细想想,这是有道理的……如果一项任务失败,WhenAny 正常完成,WhenAll 异常完成。那么,您的建议是我应该简单地使用WhenAll,还是有其他好的选择?
    • WhenAny 当您只想在任何任务以一种或另一种方式完成时继续时很好。如果你想检查任何任务是否失败,那么你应该使用WhenAll,这是正确的做法。
    猜你喜欢
    • 1970-01-01
    • 2021-03-16
    • 2010-11-16
    • 2012-01-22
    • 1970-01-01
    • 2020-11-16
    • 2010-11-25
    相关资源
    最近更新 更多