异步/等待抛出未处理的异常

3
我正在尝试从任务中实现异常处理,但我似乎无法做到。我找到了一些模式示例,但无论我尝试什么,我总是似乎从任务本身中得到未处理的异常。我一定漏掉了什么,但我看不出来。非常感谢任何帮助。
我尝试过在MSDN上找到的一个示例,但对我无效:

https://msdn.microsoft.com/en-us/library/dd997415(v=vs.110).aspx

我遵循了这个问题的答案,但当我在Visual Studio中运行修复程序时,它仍然会抱怨未处理的异常:

ContinueWith TaskContinuationOptions.OnlyOnFaulted does not seem to catch an exception thrown from a started task

这是我最初编写的代码:

static void Main(string[] args)
{
    TestAsync().ContinueWith(t =>
    {
        Console.WriteLine(t.Exception.ToString());
    }, TaskContinuationOptions.OnlyOnFaulted);

    Console.ReadKey();
}

static async Task<IEnumerable<string>> TestAsync()
{
    IEnumerable<string> list = null;

    try
    {
        list = await TestTask();
    }
    catch (Exception)
    {
        Console.WriteLine("Caught!");
    }


    return list;
}

static Task<IEnumerable<string>> TestTask()
{
    var task = new Task<IEnumerable<string>>(() =>
    {
        throw new AggregateException("This is a test");
    });

    task.Start();

    return task;
}

我不是很清楚 - 你期望发生什么?我只看到一个抛出、捕获和重新抛出的路径。这会导致异常未被处理。 - Glorin Oakenfoot
感谢您的回答。我希望在TestTask()中抛出的异常会出现在它返回的任务的Exception属性中,但是当我在Visual Studio中运行此示例时,它会突出显示TestTask()中的throw并说它是未处理的异常。我也很惊讶MSDN上的示例也在做同样的事情。 - Simon Stanford
我已经更新了示例代码,这样它就可以更好地展示我所尝试的事情。 - Simon Stanford
1个回答

5

当VS断开调试时,只需点击继续,你会看到它进入了ContinueWith。这只是调试器的一个小问题,因为它找不到在你的代码中处理异常的try/catch语句。

如果你不想让调试器停止并显示消息,你需要在调试器选项中禁用“仅限我的代码”,这样Task中的try/catch就会被视为捕获异常的内容。


哇 - 真的只有这些吗?我确实注意到如果我在异常后继续执行,它会到达我的ContinueWith,但我担心如果代码在发布中执行,那么它将到达未处理的异常而无法继续执行。 - Simon Stanford
感谢您的帮助。我已在发布模式下测试了上述代码,并且它按预期工作。当开发更大型的应用程序并需要处于调试模式时,我可以看到这可能有点麻烦,但我想这就是“仅限我的代码”选项使用的时候。 - Simon Stanford

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接