C# 如何在Visual Studio中忽略异步方法的特定异常实例(引发时中断)

C# 如何在Visual Studio中忽略异步方法的特定异常实例(引发时中断),c#,visual-studio,exception,async-await,C#,Visual Studio,Exception,Async Await,如果我将VS设置为在抛出给定类型的异常时中断,并且调试器在某段代码处停止,那么我会在相同的异常的每个父堆栈帧上寻找继续运行(F5)和不中断的可能性 换句话说,我希望有一种可能性,可以忽略异常的实例,用于其stackframe的其余部分(假设它被捕获在上面的某个地方) 我发现的唯一方法是乏味的(如果在某些情况下经常抛出此类异常,则容易出错):取消选中“抛出此类型时中断”复选框,继续执行,立即在“异常设置”窗格中重新激活异常 编辑:澄清第一个答案 我忘了提到(因为我不知道这是相关信息)我使用异步方

如果我将VS设置为在抛出给定类型的异常时中断,并且调试器在某段代码处停止,那么我会在相同的异常的每个父堆栈帧上寻找继续运行(F5)和中断的可能性

换句话说,我希望有一种可能性,可以忽略异常的实例,用于其stackframe的其余部分(假设它被捕获在上面的某个地方)

我发现的唯一方法是乏味的(如果在某些情况下经常抛出此类异常,则容易出错):取消选中“抛出此类型时中断”复选框,继续执行,立即在“异常设置”窗格中重新激活异常


编辑:澄清第一个答案

我忘了提到(因为我不知道这是相关信息)我使用异步方法。我将您的示例修改为async,如下所示:

    public static class Program
{
    public static void Main(string[] args)
    {
        try
        {
            Alpha();

        }
        catch (Exception e) // don't try this at home kids
        {
            // we should never get here in this example
            throw;
        }
    }


    private static async Task Alpha()
    {
        try
        {
            await Bravo(); //  *** 4 ***
        }
        catch (Exception e)
        {
            // debugger won't stop here because we didn't re-throw
        }
    }

    private static async Task Bravo()
    {
        try
        {
            await Tango(); //  *** 2 ***
        }
        catch (Exception)  // don't try this at home kids
        {
            throw;  // *** 3 *** debugger will stop here again because we are re-throwing
        }
    }

    private static async Task Tango()
    {
        var x = 1;
        var y = 0;
        var c = x / y; //  *** 1 ***

    }
}
调试器将按编号顺序在所有四个标记点停止。因此,它不仅在撤退时停止,而且在两者之间等待。对于深层调用层次结构,可以说这干扰了我的调试流程

因此,总而言之,我需要一个异步调用的解决方案,以避免在导致异常的stackframe和最终捕获异常的stackframe之间的每次等待时都重新中断

可能吗?


随着新信息在问题中变得明显,这个答案可能不再合适


如果我将VS设置为在抛出给定类型的异常时中断,并且调试器在某段代码处暂停,那么我将寻找继续运行(F5)的可能性,而不是在同一异常的每个父堆栈帧上中断

我发现的唯一方法是乏味的(如果在某些情况下经常抛出此类异常,则容易出错):取消选中“抛出此类型时中断”复选框,继续执行,立即在“异常设置”窗格中重新激活异常

在没有看到代码的情况下,我只能假设您正在重新抛出相同的异常

考虑以下代码:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Alpha();

        }
        catch (Exception e) // don't try this at home kids
        {
            // we should never get here in this example
            throw;
        }

    }

    private static void Alpha()
    {
        try
        {
            Bravo();
        }
        catch (Exception e)
        {
            // debugger won't stop here because we didn't re-throw
        }
    }

    private static void Bravo()
    {
        try
        {
            Tango();
        }
        catch (Exception)  // don't try this at home kids
        {
            throw;  // debugger will stop here again because we are re-throwing
        }
    }

    private static void Tango()
    {
        var x = 1;
        var y = 0;
        var c = x / y;
    }
}
当抛出
System.DivideByZeroException
时,调试器设置为中断,调试器将:

  • Tango
    中首先停止,尝试将其除以零,并引发第一个异常
  • 在再次抛出异常的
    Bravo
    中的
    catch()
    处理程序中再次停止
  • 但它不会在
    Alpha
    中停止,因为我会默默地吃掉异常


    您看到的行为是故意的。

    啊,是的,但请参见我上面的编辑。这对异步方法不起作用。欢迎提供更多信息。是的,很遗憾,我认为我的答案现在没有多大用处。正如您在文档中指出的那样,等待和抛出异常时的行为非常有趣。:)此文档共享了有关为什么在异步中未截获异常的有用信息:。感谢链接(书签),但在这里的问题中,我考虑捕获的异常(而不是未处理的异常)。@JackZhai MSFT谢谢,但这不是我们谈论的不正确的
    Async
    code。因为您不等待Alpha(),所以程序在其余代码完成之前终止。在我的机器上,程序在
    Tango()
    甚至试图除以零之前终止,更不用说抛出异常了。此外,您甚至没有创建任何
    任务
    sWhoops忽略最后,我现在正在使用我的家用计算机,并且没有打开“中断异常抛出”。给我一点时间。是的,不等待Alpha()在实际的应用程序代码中是有问题的,在这个例子中,它与我们正在讨论的问题无关,所以请忽略它;)但是随着break on exc.抛出,这个问题在example.btw中变得很明显,msdn文档说:“如果您等待一个返回导致异常的异步方法的任务,那么wait操作符将重新引发异常。”(请参阅)。所以,基本上,我是在问“如何在抛出时忽略break-on-bound中的重试”。:-/我对标题做了一些修改,并添加了一个新的
    标记
    ,希望其中一位异步大师能提供帮助:)