【问题标题】:MFC application freezing while updating CListCtrl更新 CListCtrl 时 MFC 应用程序冻结
【发布时间】:2015-07-03 13:07:54
【问题描述】:

我的 MFC 应用程序中有一个 CListCtrl。当我从服务器收到一些通知时,需要更新列表。当通知较少时更新列表效果很好,因为列表上的操作较少。但是在负载过重的情况下,列表控制,然后应用程序会冻结。

我知道在批量更新的情况下会在单独的线程中更新 UI 项目,但在这种情况下,我的通知可以以任何顺序和任何数量出现,我需要以这样的方式处理,即我的主线程没有被阻止。

如果有人之前遇到过这个问题,请提出这个案例的方法。

【问题讨论】:

  • 嗯 ... UI 冻结,因为消息循环无法对即将发生的事件采取行动。您必须将需要一些时间才能完成的函数移到工作线程中。 ......嗯......也可能有另一种方式,但我不确定。也许可以在函数中的单独消息循环中处理即将发生的事件。但这可能是糟糕的设计并导致其他陷阱孔。
  • CListCtrl 通常用于显示要从中选择的项目列表,这意味着一个很小的相当静态的列表。在我看来,CListCtrl 不适合您要完成的工作。我将研究CScrollView 方法,而不是CView,它具有处理滚动条的附加功能。然后有一个通知列表,随着通知的到来而更新,并在可视区域中显示这些通知。换句话说,采用更多的文档视图方法,其中文档是通知列表。
  • 您应该考虑使用virtual CListCtrl。这种控制风格适用于大量数据,用于缓存数据并仅显示需要的数据。

标签: c++ multithreading mfc clistctrl


【解决方案1】:

您可以将所有更新放入队列中。然后在 OnIdle 函数中从队列到控件进行有限数量的更新。当您的 GUI 消息队列为空时,将调用 OnIdle。它最多可以进行 20 次更新,然后返回。主线程将处理任何 GUI 输入,并在完成后再次调用 OnIdle。通过这种方式,您可以在保持 GUI 活跃的同时延迟和分散更新。

【讨论】:

    【解决方案2】:

    我遇到了类似的情况,并使用计时器解决了它。只有当 Timer 打勾时,ListCtrl 才会更新。

    旁注:你应该这样做

    SetRedraw(FALSE);
    

    批量更新之前

    SetRedraw(TRUE);
    

    之后。

    在进行批量操作时,您不应该让控件在一项一项级别上自行绘制。

    【讨论】:

      【解决方案3】:

      使用线程。我遇到了同样的问题,我只是通过在线程函数中将元素添加到 clistctrl 的循环来解决它。也就是说,线程中的 POSTMESSAGE() 函数是否应该在我们想要添加元素的时候被调用。 MFC Application getting stuck when adding list control elements 另请参阅上面的链接以获得一些想法

      【讨论】:

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