.NET/C#调试:如何调试经典的heisenbug?

ber*_*tie 16 .net c# visual-studio

最近,我遇到了一个经典的Heisenbug.情况如下:

  • 我在一个面板中有一个树列表,主视图,在右边的另一个面板中有一个详细视图,它显示有关当前所选树节点的信息.(与Windows资源管理器非常相似.)
  • 当我向树添加新节点时(想想在Windows资源管理器中右键单击文件夹并说"新建 - >文件夹"),新选择的节点将被选中.
  • 这是错误:右侧的详细视图应该更新以显示新节点.但事实并非如此.我必须切换到另一个树节点一次,然后才能在详细视图中看到有关新节点的信息.

该错误很容易重现,并在"发布"和"调试"构建配置中发生.但是:只要我在事件处理程序中设置断点(对于"添加新节点"菜单项)并启用它,一切正常=> Heisenbug!我不需要做任何真正的调试.在断点被击中后单击"继续"就足够了.

为了更好地理解,我制作了一个视频来说明正在发生的事情.

我能想到摆脱这个问题的一切都是让线程(应用程序是单线程的)睡眠几秒钟,但这不起作用.

我非常感谢有关我可以尝试确定问题原因的任何建议.或者有人猜测原因?

我的目标是3.5框架并使用x86作为解决方案平台.树列表控件来自DevExpress的 WinForms控件; Visual Studio版本是2010年.

谢谢


更新3:问题已解决.问题是对细节视图的Focus()方法的调用没有触发GotFocus事件,这对于更新细节视图至关重要.(我不知道为什么,可能它已经有了焦点.)然而,该方法没有失败,它根本没有做任何事情.

现在我只关注另一个控件,然后再集中细节视图,就是这样.调试期间一切正常的原因是从Visual Studio切换回我的应用程序正确地将焦点设置在详细视图上.

追捕此问题的一个主要障碍是在GotFocus事件处理程序中设置断点是无用的:只要您尝试从Visual Studio切换回应用程序,GotFocus事件就会重新触发,并且您会陷入无尽的境地环.关于如何解决这个问题的评论是值得欢迎的.

无论如何,我的具体问题已经解决了.

非常感谢所有回答或评论的人.这对我帮助很大.


更新2:在我的代码中,我选择树中新创建的节点.这会触发FocusedNodeChangedEvent.在相应的事件处理程序中,我更新详细视图并调用其Focus()方法.

当没有设置断点时,似乎失败了.我认为在调试过程中触发正确更新的原因是详细视图会自动获得焦点.


窗口消息

更新1:以下是Eddy的答案提供的窗口消息.(已删除的长邮件列表)

Pre*_*gha 2

System.Diagnostics.Debugger.Break()放入另一个窗口的更新例程中。然后,当错误出现时,将触发运行时断点,您可以查看堆栈。