static void Main(string[] args) { // try // #2 { string x = null; // #1 AssertNotNull(x,nameof(x)); } // catch (ArgumentNullException) { } // #2 Console.WriteLine("Passed."); Console.ReadKey(); } [DebuggerHidden] public static void AssertNotNull<T>(T arg,string argName) where T : class { if (arg == null) throw new ArgumentNullException(argName); }
对于从VS2008开始的任何VS(没有检查早期版本)的行为是相同的.
如果您在调试(使用标准调试设置)下运行它,则在您修复代码(使用EnC)之前,不能继续执行.由于[DebuggerHidden]和“Unwind stack on unhandled exception”设置组合(默认情况下启用设置),点击F5将重新运行断言.
要修复代码,只需用对象x =“”替换#1行,然后再设置下一个语句并再次按F5.
现在,为ArgumentNullException启用“抛出”,取消注释标有#2的行.
行为改变:你再次停止断言,但堆栈不解开(容易用CallStack窗口检查). F5将从抛出异常的地方继续.
好的,所以现在的问题是:
有没有办法在打破处理的异常时启用自动堆栈展开?
隐藏的VS选项,现有的扩展名或(可能)可以从我自己的扩展名使用的API?
UPD:为了澄清这个问题:我想用断言断言,用编辑编辑代码并继续,将下一个语句设置为固定代码并继续执行.
如果异常没有被捕获到堆栈,它的工作原理.
UPD2由Hans Passant提出:发布an suggestion on UserVoice.随意投票:)
解决方法
and uncomment the lines marked with #2
这是你问题的关键部分.你改变了不止一件事情,关键的变化是你改变了堆栈解开的方式.您喜欢的调试器选项名为“解开未处理的异常堆栈”.问题是,没有任何未处理的异常了.您的catch子句处理它,现在是解开堆栈的CLR.
而且它一定是CLR,它可以解开,调试器没有选择在你要求的第一次机会异常中断.而SetNext在这一点上无法正常工作.其中,如果我正确地解释这个问题,你真的很希望,因为你需要做的下一步是忙碌的工作,单步通过catch块是不是巨大的喜悦.
虽然没有实施,但我觉得在技术上是可行的.但是,只是因为我非常不知道调试器团队必须做多少工作.这是一个很好的要求,使E C工作更好,你可以propose it here.发布网址到你的建议作为一个commnent,很好的赔率,它会得到一堆票.我会投票支持