我有一个非常严重的多线程调试问题。在与串行设备交互时我遇到了某种时序问题,我需要跟踪它。我有三个主题:
我的问题实际上与调试这种情况有关。看起来我在每个线程中的每一行都必须有一个断点才能进行调试;如果我在一个线程中断,调试器将不会单步执行该线程。我知道其他线程将继续更新,但是我不应该在调试器中执行正常的线程,即从一行到下一行?然后,我可以使用'threads'选项卡在线程之间切换。
我提到我在WPF,因为我不知道这是否会改变情况;也许它确实如此,也许它没有。状态检查线程是UI控件的一部分,因为只需在UI启动时检查状态。该控件位于与主应用程序不同的库中。
答案 0 :(得分:7)
当调试器在断点处停止时,默认情况下它将挂起所有其他线程。但是当你继续步骤或继续时,所有3个线程都会恢复。当您单步执行代码时,调试器基本上会在下一行设置临时断点并恢复所有线程。其他2可能有机会在该虚拟断点被击中之前运行。
您可以在调试时冻结其他线程
当你处于断点时选择 Debug | Windows |线程即可。选择您不感兴趣的主题并右键单击,选择冻结。这将让您专注于您正在逐步完成的一个主题。
答案 1 :(得分:1)
如果您的代码以单一的方式单步执行,有时可能是由简单的pdb文件损坏引起的。您的代码上的“全部重建”将从头开始重新生成并解决任何此类故障。
要记住的另一件事是,在调试器中停止一个线程会导致您在发布版本中看不到的各种异常时序。例如:
当您在断点处停止时,串行端口将始终继续运行(在硬件/驱动程序级别) - 当您下次尝试步进代码时,它可能会突然收到大量数据。使用异步回调,这可能是“有趣的”。
停止一个线程会扰乱正常的时间点,这样线程到线程的同步就会搞砸了。
答案 2 :(得分:1)
我和Jason在一起,踩着将不再显示真相。
使用Interlocked.Increment增加计数器并将计数器添加到输出(本地文件最好)的方法,你最好不要使每个代码行进行检测。
需要计数器,因为实际事件的顺序并不总是与写入文件的顺序相同。命名线程或在输出中使用ID值。我使用MS Excel打开文件并根据线程为所有行着色,这样我就可以非常清楚地看到交错操作。
我甚至写了一个包装器来锁定{}当每个锁开启/关闭时哪些乐器。
同步问题对于拍摄是可怕的,所以我建议不要花费超过重构的费用。有时它表明你所采取的方法是次优的。
请记住在必要时使用volatile。