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

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

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

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

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

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

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

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

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

  • 使用BackgroundWorker
  • 调用Application.DoEvents()

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

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

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

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

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

你有几个选择:

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