繁体   English   中英

没有后台工作程序,为什么UI不能及时更新?

[英]Why exactly is UI not updating in time without background worker?

我编写了一个单线程程序(winforms meh),并希望它的行为如下:

  1. Mainform开始进度显示表单
  2. 进度表已完全呈现
  3. 进度表单接收事件操作Started,它将旋转圆圈的图片添加到表单中
  4. 持久的操作开始
  5. 进度表接收事件operationCompleted或operationFailed并设置适当的图像

发生的事情很混乱。

  1. Mainform开始进度显示表单
  2. 进度表未完全呈现!
  3. 程序挂了一段时间
  4. 完成长时间的操作后,UI更新

为什么更新窗体滞后?

如果需要,这是简化的代码

    private bool Run(int commandIndex, string fullCommand)
    {
        if (operationStarted != null)
            operationStarted(commandIndex);

        // start long lasting external process

        if (exitCode != 0)
        {
            if (operationFailed != null)
                operationFailed(commandIndex, Error);

            return false;
        }

        if (operationCompleted != null)
            operationCompleted(commandIndex);

        return true;
    }

正确设置了operationStarted,operationFailed和operationCompleted以更新适当的图像。

这已大大简化,但我认为就足够了。

Windows由在队列系统中处理的消息驱动。

当显示一个窗口时,一个或多个消息被放入队列中,并且必须进行处理。

这些消息之一将是绘画消息。 响应此消息,您的程序应该在屏幕上绘制窗口(或其内部内容)。

队列系统的处理方式是您的表单由一个连续拥有以下功能的线程所拥有:

while (true)
{
    var message = GetNextMessage();
    if (message == none) break;
    ProcessMessage(message);
}

此循环处理的消息之一是一条消息,指示您的程序用户单击了表单按钮。

作为响应,.NET将该消息作为事件路由到事件处理程序,通常类似于“ button1_Click”之类,然后执行。

在事件处理程序(此click方法)返回之前,此循环不会处理任何消息。

这样,如果该按钮单击事件正在执行较长的操作,则您将被称为“阻止UI”,这基本上是“您没有以有序的方式返回到消息循环中”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM