如何强制调试器跳过一个方法及其进入Application.Run()后调用的任何内容?

时间:2018-05-13 01:17:44

标签: c# .net winforms visual-studio visual-studio-2010

TL; DR - 是否有'递归'[DebuggerStepThrough]

我是否可以在方法上使用某个属性,以便在使用 Debug>时在一个空闲的WinForms表单上打破所有,然后单步执行Application.Run(),这样当一个事件调用该方法时,该方法或它调用的任何东西都不会触发断点?

以下是一些简单的示例代码,用于说明问题¹:

static void Main() {
  Application.Run(new MyForm());  //I step (F11) into here to wait for events of interest
}

string GetSome { 
  get {                  //I don't want to wind up on a breakpoint here
    return "Some";       //as a result of OnActivated() being called!
  }                      //But I *DO* want to be able to step in here otherwise,
}                        //(e.g. as a result of OnClick() being called.²

[DebuggerStepThrough]    //Not interested in this event or anything it calls
protected override void OnActivated(EventArgs e){  
  string come = GetSome;
}

protected override void OnClick(EventArgs e){  //But I *AM* interested in this event
  string come = GetSome;
}

我在做什么:一旦我的WinForms表单完全初始化,得到了焦点,现在处于空闲状态(消息循环中没有排队的消息)(标记1) ,我用 Debug>暂停空闲表单全部打破。表单处于空闲循环中,因此调试器将最顶层的堆栈帧显示为 [外部代码] ,前一个堆栈帧为Application.Run()行。然后我点击了F11(Step Into)。表单的消息循环恢复,表单重新激活并获得焦点。 (标记2)一旦托管框架出现在堆栈顶部,调试器现在就会暂停 - 例如一旦上述代码中的一个事件发生。 (标记3)重新激活表单会导致OnActivated()被调用。

所需行为 我希望调试器忽略OnActivated()以及它可能调用的任何其他内容。单击恢复的表单后,我希望调试器在OnClick()上暂停,因为调试器正在等待托管帧到达堆栈顶部。

实际发生的事情: 调试器忽略OnActivated()(因为它标记为[DebuggerStepThrough]) - ,但暂停在GetSome getter - bad 中。此时:

  • 如果我单步执行GetSome getter,表单会再次重新激活,然后我回到标记2 并且我处于循环中。
  • 如果我走出({+ 1}} getter的Shift + F11,它与按F5的效果相同 - 程序的执行完全恢复,调试器不再需要在下一个托管处暂停堆栈框架。我回到标记1

有趣的是,调试器实际上忽略了“调试>选项>调试>常规>在标记3 上跳过属性和运算符”选项。如果我在启动表单时手动进入(F11)GetSome,启用“跳过属性和运算符”,调试器不会暂停{来自Application.Run()的{​​1}} getter!

¹代码中的任何地方都没有设置明确的断点。在我正在处理的实际代码中,我试图让调试器忽略一些特定的重绘事件(以及他们从其他类调用的任何方法和访问器),同时能够使用“Break All + F11”作为步入任何下一个事件的快捷方式(有许多可能性),而不必在每个事件上设置明确的断点。

²我不能仅仅标记“无趣”事件使用GetSome属性调用的所有其他方法的原因有两个:我所谓的几个“无趣”事件我已经调用了数百个其他方法 - 这是很多重构和可见的杂乱添加;当然,当我真正需要调试时,我将失去逐步完成这些方法的能力。

0 个答案:

没有答案