【问题标题】:Find which module is blocking the UI thread查找哪个模块阻塞了 UI 线程
【发布时间】:2010-11-02 15:54:36
【问题描述】:

这是一个两部分的问题:

  • 我正在处理一个大型项目,其中由不同团队开发的多个插件被加载到一个通用容器外壳中。有时我可以看到我的 UI 更新被阻止,因为有多个并行 UI 更新,我想知道是否有办法找到哪个组件阻止了 ui 线程

  • 在 .net 中如何创建需要专门的 UI 密集型工作的单独 UI 线程?

非常感谢您的帮助。谢谢。

【问题讨论】:

    标签: c# .net multithreading user-interface


    【解决方案1】:

    使用调试器。当您发现它阻塞时,调试+全部中断。然后 Debug + Windows + Threads 并选择主线程。调用堆栈窗口会显示它正在做什么。

    一个极端情况是这些插件使用大量对 Control.Begin/Invoke 或 Dispatcher.Begin/Invoke 的调用。在这种情况下,您的 UI 线程不会被阻塞,它只是被调度委托目标的请求所淹没。并且不再执行其正常职责,例如重新绘制窗口和响应鼠标和键盘事件。除了与插件作者合作让他们改过自新之外,您几乎无能为力。

    您已经有了一个 UI 线程,即创建第一个窗口的线程。创建具有自己的窗口的其他线程是可能的,但会导致窗口 Z 顺序无法解决的问题(一个窗口将在另一个应用程序的窗口下方消失)以及窗口互操作线程痛苦的慷慨帮助。

    【讨论】:

    • 好吧,它没有显示所有外部代码,但 ui 仍然冻结,无响应或非常慢
    【解决方案2】:

    Visual Studio 2010(在更高版本的 SKU 中)包含检查这一点的功能。如果您在 Concurrency Profiler 下运行程序,您可以准确地看到发生死锁时哪些线程正在等待哪些锁。另外,它会突出显示死锁(我相信是鲜红色),以便于追踪。

    【讨论】:

    • 我们该怎么做? ty 非常我真的需要找出哪些块使它冻结 ui 线程
    • @MonsterMMORPG 在并发分析器下运行您的程序。它显示何时被阻塞、哪些线程和任务被阻塞,以及它们正在等待什么。
    【解决方案3】:

    您可以采取的一种方法(尽管可能需要进行一些重新设计)是禁止所有插件逻辑在 UI 线程中运行。所有需要更新 UI 的操作都必须通过定义明确的服务接口进行路由,这些接口可以解释、调度甚至限制 UI 更新。仅当您的插件不是以 UI 为中心并且您有一个服务模型允许您将插件操作的数据与该数据的可视化隔离时,这才是实用的。在不了解您的应用程序的情况下,我无法给出更具体的建议。

    【讨论】:

      【解决方案4】:

      以下是我快速提出的两个可能的解决方案。我相信还有其他同样有效的解决方案。

      选项 1: 不使用推送模型(通过ISynchronizeInvoke 方法),而是切换到 UI 查询插件以获取更新的拉取(或轮询)模型。这具有以下优点。

      • 它打破了Control.Invoke 强加的 UI 和工作线程/插件线程之间的紧密耦合。
      • 它将更新 UI 线程的责任放在它本来应该属于的 UI 线程上。
      • UI 线程可以决定更新的时间和频率。
      • 不存在 UI 消息泵溢出的风险,就像工作程序/插件线程启动的封送技术一样。
      • 工作线程/插件线程无需等待确认更新已执行,即可继续执行后续步骤(即,您可以在 UI 和工作线程/插件线程上获得更高的吞吐量)。

      选项 2: 让插件接受 ISynchronizeInvoke 实例,而不是实际的 FormControl。这个特殊的同步对象将使用一个专用线程和一个充当插件和 UI 之间缓冲区的队列来实现。它将通过普通的InvokeBeginInvoke 方法接受更新消息,这意味着您可以保持插件架构和接口基本完整,然后在某种类型的过滤、合并和限制操作后将这些消息转发到 UI已经发生。同步对象中存在的更新消息的数量将随着 UI 和插件线程工作负载的变化而起起落落。随着消息速率的增加,它可能足够聪明地改变其转发策略。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多