在代码完成之前,GUI不会更新

时间:2010-10-18 12:37:08

标签: c# label

嘿,我有一系列代码如下:

label.Text = "update 0";
doWork();
label.Text = "update 1";
doWork2();
label.Text = "update 2";

基本上,在完成所有代码执行之前,GUI根本不会更新。如何克服这个?

4 个答案:

答案 0 :(得分:16)

丑陋的黑客就是使用Application.DoEvents。虽然这有效,但我建议不要这样做。

更好的解决方案是使用BackgroundWorker或单独的线程来执行长时间运行的任务。不要使用GUI线程,因为这会导致它阻塞。

需要注意的一件重要事情是,必须在GUI线程上对GUI进行更改,因此您需要将控制权转移回GUI线程以便标记更新。这是使用Invoke完成的。如果您使用BackgroundWorker,则可以使用ReportProgress - 这将自动为您调用Invoke。

答案 1 :(得分:2)

当UI获取重绘屏幕的WM_PAINT消息时,UI会更新。如果您正在执行代码,则不执行消息处理例程。

因此,您可以执行以下操作以启用消息处理程序的执行:

Application.DoEvents,调用消息处理程序,然后返回。它不适合大型工作,但对于小型程序,它可以是一个更简单的解决方案,而不是引入线程。

答案 2 :(得分:1)

目前,所有处理都在主(UI)线程上执行,因此所有处理必须在UI线程之前完成,然后才有重新绘制UI的空闲周期。

你有2种方法可以克服这个问题。不推荐的第一种方法是使用
Application.DoEvents();每当您希望处理Windows消息队列时运行此命令。

另一种推荐方式:创建另一个线程来进行处理,并使用委托将UI更新传递回UI线程。如果您不熟悉多线程开发,请尝试使用BackgroundWorker。

答案 3 :(得分:1)

以这种方式运行代码时,GUI无法更新。 Windows上的GUI依赖于消息处理,当您在代码中时,消息处理将停止 - 无论您对标签,按钮等做什么,它们都会在您的代码退出后更新,并且表单的主要消息循环是处理。

这里有几个选项:

  • 将处理移至其他线程并面对Invoke()situtations
  • 调用DoEvents()并允许gui在您的DoWork调用之间刷新
  • 完成所有工作并稍后更新