在繁重的CPU负载下交叉线程BeginInvoke阻塞

时间:2012-08-14 22:53:24

标签: .net winforms multithreading

我有一个Windows窗体用户控件,其中包含第三方图像显示控件,该控件使用BeginInvoke委托调用从单独的线程更新。

在CPU负载过重的情况下,UI会锁定。当我附加一个调试器时,它总是在更新第三方图像控件的同一行代码上。

    public ICogImage DisplayImage
    {
        get { return this.ResultImageCogDisplay.Image; }
        set 
        {
           this.BeginInvoke((ThreadStart)delegate
            {
                this.ResultImageCogDisplay.Image = value;
            });

        }
    }

如果我注释掉了setter的实现,那么问题就会消失。

任何人都可以解释为什么会这样吗?

更多信息:

  • 图像更新事件是从帧抓取卡周期性地(~200ms)生成的。事件是在不同的线程上引发的。
  • 我相信第三方图像控件使用ActiveX,它是康耐视视觉处理框架的一部分。
  • 图像是约。 900x800 8位灰度
  • 表格中有4个这样的控件,每个控件都来自不同的线程,不同的图像。
  • 我在使用和不使用IsInvokeRequired()检查时尝试过,它似乎没有任何区别。

PostMessage队列上的消息数是否有任何限制,我在高CPU负载下遇到了什么?

2 个答案:

答案 0 :(得分:4)

BeginInvoke对要在UI线程上执行的操作进行排队。如果你排队的事情很多,那么用户界面无法跟上它们,你就会压倒UI线程并且它会显示为挂起。尝试将事件限制在每秒一次,以查看是否有帮助。

答案 1 :(得分:0)

Windows消息队列条目确实存在限制(至少在32位系统上存在)10,000个条目。在此之前很久,通过发布消息比GUI可以处理它们更快地完成GUI的筛选 - 我经常这样做:((

通常,我的设计使用一个对象池来进行线程间通信,所以我解决了这个问题,因为如果GUI没有足够快地返回'used'对象,那么生产者线程在池队列上被阻塞,因此提供整体流量控制。当然,在停止GUI锁定时,如果您的帧速率要求无法满足,这无济于事:(