2

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

在繁重的 CPU 负载下,UI 会锁定。当我附加调试器时,它始终位于更新第 3 方图像控件的同一行代码中。

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

        }
    }

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

谁能解释为什么会这样?

更多信息:

  • 图像更新事件由图像采集卡定期(约 200 毫秒)生成。这些事件在不同的线程上引发。
  • 我相信第 3 方图像控件使用 ActiveX,它是康耐视视觉处理框架的一部分。
  • 图像约为。900x800 8 位灰度
  • 表单上有 4 个这样的控件,每个控件都来自具有不同图像的不同线程。
  • 我已经尝试过使用和不使用 IsInvokeRequired() 检查,它似乎没有任何区别。

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

4

2 回答 2

4

BeginInvoke将要在 UI 线程上执行的操作排队。如果您排队执行的操作太多,UI 无法跟上它们,您将压倒 UI 线程并且它会显示为挂起。尝试将事件限制到每秒一次,看看是否有帮助。

于 2012-08-14T23:07:53.630 回答
0

Windows 消息队列条目确实存在 10,000 个条目的限制(至少在 32 位系统上)。在那之前很久,通过发布消息比 GUI 处理它们的速度更快来调整 GUI 是很容易的——我经常这样做:((

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

于 2012-08-14T23:45:59.820 回答