跳过第一次例外

本文关键字:第一次 | 更新日期: 2023-09-27 17:49:01

我继承了一个项目,当在调试中启动时,抛出了8-10k NotImplementedException s的某个地方。正因为如此,在调试时,应用程序需要一分钟才能启动。每一个。单身。时间。

我与项目的原始开发人员交谈过,他们对这个问题的解决方案是"只需按Ctrl+F5启动,而无需附加调试器"。除了这是开发历史上最糟糕的问题解决方案之一之外,它确实有效,并且应用程序立即启动。我正在尝试学习这个新的代码库,所以只是跳过调试器不是我的选择。

显然,我知道任何应用程序都不应该一开始就有1万个异常,但在我开始修复之前,我必须能够调试程序。

我想在没有附加调试器的情况下启动时以相同的方式抑制或跳过第一次机会异常。我已经查看了这个线程,并将[DebuggerNonUserCode]属性应用于相关方法,但它只阻止将异常写入输出窗口。该程序启动仍然需要一分钟多的时间。这可能吗?

编辑:

我忘了说,我没有在Debug->Exceptions窗口中检查任何东西。此外,所有的异常都包装在Try.. Catch语句

跳过第一次例外

  1. 检查您的Visual Studio设置在Debug -> Exceptions -> Common Language Runtime Exceptions -> System -> System。NotImplementedException,并确保未检查抛出。(默认情况下不应该检查,但这将导致它停止,即使异常被处理)。
  2. 蹩脚的解决方案:在代码的一部分,这是过去的所有异常,你想开始调试,把以下行

    System.Diagnostics.Debugger.Launch();
    System.Diagnostics.Debugger.Break();
    

您可以开始按Ctrl+F5,然后当它在代码中到达该点时提示附加调试器。

EDIT:主要编辑以消除我清晨的脑损伤。

为我的观点提供一些额外的信息,试图展示可以用来减少异常数量启动时间的步骤。这段代码允许我用来分析N个调用,而不会抛出异常:

void Run(int n, bool doThrow, bool doExcept)
{
    for (int i = 0; i < n; i++)
    {
        if (doExcept)
        {
            try
            {
                if (doThrow)
                    throw new NotImplementedException();
            }
            catch (NotImplementedException)
            {
            }
        }
    }
}

在VS主机进程的调试模式下,当Exceptions对话框中没有设置复选标记时,测试场景给出以下数字。

1; 4.000 msec
1: 0.000 msec (no throw)
1: 0.000 msec (no throw, no except)
10; 32.000 msec
10: 0.000 msec (no throw)
10: 0.000 msec (no throw, no except)
100; 780.000 msec
100: 0.000 msec (no throw)
100: 0.000 msec (no throw, no except)
1000; 7251.000 msec
1000: 0.000 msec (no throw)
1000: 0.000 msec (no throw, no except)
10000; 35694.000 msec
10000: 0.000 msec (no throw)
10000: 0.000 msec (no throw, no except)

很明显,异常的数量在这里很重要,正如您所期望的那样。我将在一分钟内编辑更多来自不同场景的数字。

在VS托管进程的调试中,异常大约需要3.5-7毫秒。在调试模式下禁用VS主机进程(它仍然允许调试)将每个异常的时间降至1.9 msec:

1; 3.000 msec
10; 21.000 msec
100; 198.000 msec
1000; 1917.000 msec
10000; 19065.000 msec

和发布模式没有VS托管过程大约需要1.8毫秒(编辑后插入我的笔记本电脑):

1; 3.000 msec
10; 17.000 msec
100; 184.000 msec
1000; 1823.000 msec
10000; 18248.000 msec

并且在调试器之外的发布模式下运行每个异常大约0.016 msec:

1; 1.000 msec
10; 1.000 msec
100; 3.000 msec
1000; 19.000 msec
10000; 138.000 msec

所以在我的测试设置中,它仍然不会"立即"从调试器加载10k异常。不过,这可能与我在2010年安装时遇到的问题有关(我后来重新安装了)。它在调试器之外的加载速度非常快。

这是我完整的测试设备:

static void Main(string[] args)
{
    Stopwatch sw = new Stopwatch();
    var p = new Program();
    int[] tests = new int[] { 1, 10, 100, 1000, 10000 };
    foreach (int n in tests) {
        sw.Start();
        p.Run( n, true, true);
        sw.Stop();
        Console.WriteLine(string.Format("{0}; {1:0.000} msec", n, sw.ElapsedMilliseconds));
        sw.Start();
        p.Run(n, false, true);
        sw.Stop();
        Console.WriteLine(string.Format("{0}: {1:0.000} msec (no throw)", n, sw.ElapsedMilliseconds));
        sw.Start();
        p.Run(n, false, false);
        sw.Stop();
        Console.WriteLine(string.Format("{0}: {1:0.000} msec (no throw, no except)", n, sw.ElapsedMilliseconds));
    }
    Console.WriteLine("Any key to exit...");
    Console.ReadKey();
}