异步任务中的异常在 Visual Studio 中被截获

本文关键字:Studio Visual 任务 异常 异步 | 更新日期: 2023-09-27 17:56:32

我想运行几个任务,其中一些任务会异步完成,然后等待所有任务完成。由于任务可能会引发异常,因此我想捕获并记录它们。示例代码:

static async Task doit(int x)
{
    try
    {
        Console.WriteLine("{0}  {1}  start", x, Thread.CurrentThread.ManagedThreadId);
        await Task.Run(() =>
        {
            Thread.Sleep(TimeSpan.FromSeconds(2 + x));  // simulate long-running stuff worth awaiting...
            if (x == 3)
            {
                throw new Exception("Exception inside task " + x.ToString());  // Simulate the async task throwing exception
            }
        });
        if (x == 2)
        {
            throw new Exception("Exception after task " + x.ToString());  // Simulate post-async task throwing exception
        }
        Console.WriteLine("{0}  {1}  end", x, Thread.CurrentThread.ManagedThreadId);
    }
    catch (Exception ex)
    {
        Console.WriteLine("{0}  {1}  Exception: {2}", x, Thread.CurrentThread.ManagedThreadId, ex.Message);
    }
}
private static void TestTasks()
{
    var tasks = Enumerable.Range(1, 3).Select(n => doit(n)).ToArray();
    Console.WriteLine("Waiting");
    Task.WaitAll(tasks);
    Console.WriteLine("all end");
}

如果我从控制台运行此代码,它将按预期工作,输出如下:

1  1  start
2  1  start
3  1  start
Waiting
1  3  end
2  4  Exception: Exception after task 2
3  5  Exception: Exception inside task 3
all end

但是,如果我在 Visual Studio 中进行调试,调试器会在注意到的异常处停止,并显示 Exception was unhandled by user code 。然后我需要点击F5 Continue才能完成代码。

我注意到,如果我禁用选项 => 调试器 => Enable Just My Code ,调试器不会停止。但是,我不想永久设置它,因为我使用的某些框架处理我确实希望调试器停止的异常。

  • 为什么即使异常在 try/catch 中,调试器也会停止?
  • 如何让调试器不在此异常处停止?

异步任务中的异常在 Visual Studio 中被截获

为什么即使异常在 try/catch 中,调试器也会停止?

从技术上讲,代码引发的异常未被当前调用堆栈上的任何代码捕获。它被(编译器生成的)async状态机捕获并放置在返回的任务上。稍后,当await ed 从 Task.Run 返回的任务时,将重新引发该异常。

如何让调试器不在此异常处停止?

现在,您唯一的选择是让调试器以某种方式忽略此异常(仅禁用我的代码,禁用中断该类型的用户未处理异常,...

如果您认为VS应该在这里提供更好的用户体验,请随时打开用户语音建议。

为什么即使异常在 try/catch 中,调试器也会停止?

此行为显然取决于 Visual Studio 的版本。

我在Visual 2013中遇到了同样的问题。我尝试使用 Visual 2015 Update 1 生成和调试相同的代码。这一次,调试器正确处理了异常,并且没有停止。

没有提到您使用的是哪个版本的 Visual。如果它是早于 2015 年的版本,您可以尝试使用 Visual 2015 或更高版本,看看它是否可以解决问题。