在代码完成之前 GUI 不会更新
嘿,我有一个类似这样的代码序列:
label.Text = "update 0";
doWork();
label.Text = "update 1";
doWork2();
label.Text = "update 2";
基本上,GUI 根本不会更新,直到所有代码执行完毕。如何克服这个问题?
Hey, I have a sequence of code that goes something like this:
label.Text = "update 0";
doWork();
label.Text = "update 1";
doWork2();
label.Text = "update 2";
Basically, the GUI does not update at all, until all the code is done executing. How to overcome this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
一个丑陋的黑客是使用
Application.DoEvents
。虽然这有效,但我建议不要这样做。更好的解决方案是使用
BackgroundWorker
或一个单独的线程来执行长时间运行的任务。不要使用 GUI 线程,因为这会导致它阻塞。需要注意的一件重要事情是,对 GUI 的更改必须在 GUI 线程上进行,因此您需要将控制权转移回 GUI 线程以进行标签更新。这是使用
Invoke
完成的。如果您使用BackgroundWorker,您可以使用ReportProgress - 这将自动为您处理调用Invoke。An ugly hack is to use
Application.DoEvents
. While this works, I'd advise against it.A better solution is to use a
BackgroundWorker
or a seperate thread to perform long running tasks. Don't use the GUI thread because this will cause it to block.An important thing to be aware of is that changes to the GUI must be made on the GUI thread so you need to transfer control back to the GUI thread for you label updates. This is done using
Invoke
. If you use a BackgroundWorker you can use ReportProgress - this will automatically handle calling Invoke for you.当收到 WM_PAINT 消息以重新绘制屏幕时,UI 会更新。如果您正在执行代码,则不会执行消息处理例程。
因此,您可以执行以下操作来启用消息处理程序的执行:
Application.DoEvents()
Application.DoEvents,调用消息处理程序,然后返回。对于大型作业来说它并不理想,但对于小型程序来说,它可以是一个更简单的解决方案,而不是引入线程。
The UI updates when it get's a the WM_PAINT message to repaint the screen. If you are executing your code, the message handling routine is not execute.
So you can do the following to enable executing of the message handler:
Application.DoEvents()
The Application.DoEvents, calls the message handler, and then returns. It is not ideal for large jobs, but for a small procedures, it can be a much simpler solution, instead of introducing threading.
目前,所有处理都在主 (UI) 线程上执行,因此所有处理必须在 UI 线程有空闲周期来重新绘制 UI 之前完成。
您有两种方法可以克服这个问题。第一种方法(不推荐)是使用
Application.DoEvents();
每当您希望 Windows 消息队列得到处理时就运行此函数。另一种推荐的方法是:创建另一个线程来执行处理,并使用委托将 UI 更新传递回 UI 线程。如果您是多线程开发的新手,请尝试一下BackgroundWorker。
Currently, all of your processing is being performed on the main (UI) thread, so all processing must complete before the UI thread then has free cycles to repaint the UI.
You have 2 ways of overcoming this. The first way, which is not recommended, is to use
Application.DoEvents();
Run this whenever you want the Windows message queue to get processed.The other, recommended, way: Create another thread to do the processing, and use a delegate to pass the UI updates back to the UI thread. If you are new to multithreaded development, then give the BackgroundWorker a try.
以这种方式运行代码时 GUI 无法更新。 Windows 上的 GUI 依赖于消息处理,当您在代码中时,消息处理会停止 - 无论您对标签、按钮等做什么,它们都会在代码退出后更新,并且表单的主消息循环为已处理。
这里有几个选项:
GUI cannot update while running your code that way. GUI on windows depend on message processing, and message processing is halted while you are in your code - no matter what you do with the labels, buttons and such, they will all be updated AFTER your code exits and main messaage loop of the form is processed.
You have several options here: