c# - 检测停滞的 UI 线程

标签 c# .net multithreading locking

我有一个正在积极使用的应用程序,UI 线程很少发生“卡住”。这当然会导致应用程序变得无响应并要求用户手动终止它。

由于重现此问题的难度很大,我想开发一些工具来帮助收集有关该问题何时在现场发生以及当时发生的情况的数据。我正在考虑的是某种后台看门狗任务,它将监视来自定期调度的 UI 线程任务的“心跳”。如果它安静得太久,我可以说 UI 被有效地锁定(或者至少停滞了比我想要的更长的时间)并因此收集数据。

所以,在准备这个之前,有几个问题:

  • 这样的东西已经存在了吗?这似乎是一个相当普遍的问题,所以如果有现有的工具来帮助诊断这个问题,那么使用这些工具而不是滚动我自己的解决方案可能是值得的。
  • 我仍在争论当检测到卡住时我应该尝试收集哪些信息。有什么方法可以让我轻松获取 UI 线程的堆栈跟踪以便记录它吗?可能从所有事件线程中获取堆栈跟踪?有什么方法可以捕获完整的调试转储吗?
  • 最佳答案

    Does something like this already exist?



    是的。必须在进程之外执行此操作,因为死锁的一个很可能使诊断代码也将死锁。 DebugDiag utility明确支持挂起的应用程序。

    I'm still debating what information I should try to gather



    您从 DebugDiag 中获得的小型转储应该足以让您有机会诊断原因。演示解决死锁的示例调试 session 是 shown here .

    当然,仔细检查您的代码永远不会受到伤害。 UI 线程死锁通常由以下原因引起:
  • 在工作线程上显示一个窗口。执行此操作时,SystemEvents 类是一个非常重要的麻烦制造者。它需要在 UI 线程上触发其事件,但这需要它猜测程序中的哪个特定线程实际上是 UI 线程。一旦它猜错了,你就会在以后的任何时候陷入自发的僵局。请注意,这不需要您在自己的代码中使用 SystemEvents 类,许多控件订阅 ThemeChanged 事件以重新绘制自己。 Fwiw,我链接到的那个调试 session 演示了这样一个死锁。当心自制的启动画面、在工作线程而不是 UI 线程上创建的“进度”窗口,当然还有任何显示 UI 的工作线程。
  • 数据绑定(bind)控件,其底层绑定(bind)源在工作线程上更新。当然很常见,因为 dbase 查询往往很慢。此类控件必须首先明确地解除绑定(bind)。
  • 关于c# - 检测停滞的 UI 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21631724/

    相关文章:

    c# - 归档 zip 文件并将其保存到选择的位置,而不需要额外的文件路径?

    c# - 即使两个字符串在 C# 中相同,String Equals() 方法也会失败?

    c# - WCF 服务是否使用多线程来处理传入请求?

    c# - 为什么整数属性有时会返回 0?

    java - 具有每个请求配额的线程池执行器?

    java - 将 FX 嵌入到 swing 中时出现问题

    c# - 为什么这个 SQL Server INSERT 查询不执行?

    c# - 在代码隐藏中将数据网格列宽设置为星号

    c# - 使用 LINQ 对列表中的项目进行排名

    .net - 使用 Windows Azure 托管的连接问题