c# - .NET/C# 调试 : How to debug a classical heisenbug?

标签 c# .net visual-studio

最近,我遇到了一个经典的 Heisenbug .情况是这样的:

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

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

为了更好地理解,我做了 a video这应该说明发生了什么。

为了解决这个问题,我能想到的所有方法都是让线程(应用程序是单线程的)休眠几秒钟,但这不起作用。

对于我可以尝试确定问题原因的任何建议,我将不胜感激。或者也许有人猜到了原因?

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

谢谢


更新 3:问题已解决。问题是对详细 View 的 Focus() 方法的调用没有触发 GotFocus 事件,这对于更新详细 View 至关重要。 (我不知道为什么,可能它已经有了焦点。)但是,该方法并没有失败,它只是什么也没做。

现在我只需在聚焦详细 View 之前聚焦另一个控件,仅此而已。在调试期间一切正常的原因是从 Visual Studio 切换回我的应用程序正确地将焦点设置在详细信息 View 上。

解决此问题的一个主要障碍是在 GotFocus 事件处理程序中设置断点是无用的:任何时候您尝试从 Visual Studio 切换回应用程序时,GotFocus 事件都会重新触发,并且您陷入困境在无限循环中。欢迎就如何解决这个问题提出意见。

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

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


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

似乎在没有设置断点的情况下失败了。我认为在调试期间触发正确更新的是详细 View 自动获得焦点。


窗口消息

更新 1:以下是 Eddy 的回答提供的窗口消息。 (删除的一长串消息)

最佳答案

我第一次看到支持 SO 的视频 :)

我认为右侧 Pane 或控制组需要调用 Invalidate() - 我认为触发断点是因为它切换到 VS, overdraw window 。然后,当您再次切换回来时,它会强制重新绘制所有内容,从而使其正常工作。

关于c# - .NET/C# 调试 : How to debug a classical heisenbug?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6979132/

相关文章:

c# - SendMessage,何时使用 KEYDOWN、SYSKEYDOWN 等?

c# - "safe"可查询的服务层设计?

c++ - 如何在 Visual Studio 中处理括号形式的包含指令?

c# - .Net Core App 2.0 与 .Net Standard 2.0 库不兼容

.net - 跟踪对数据库行的更改 (SQL Server)

c++ - Visual Studio mkl_link_tool.exe 链接错误

C# MySQL 语法错误

c# - .Net - 查找数据表中的最大值

c# - 我在 sqlConnection 中发现的那些奇怪的属性是什么?

c# - 如何更改表单在呈现 View 时的操作? (又名通过 ViewBag 或 ViewData)