【发布时间】:2017-06-23 17:22:55
【问题描述】:
使用Application.DoEvents有什么必要性,什么时候应该使用?
【问题讨论】:
标签: doevents
使用Application.DoEvents有什么必要性,什么时候应该使用?
【问题讨论】:
标签: doevents
Application.DoEvents 通常用于确保在 UI 线程上执行一些长时间运行的操作时定期处理事件。
更好的解决方案就是不这样做。当您需要更新 UI 时,在单独的线程上执行长时间运行的操作,编组到 UI 线程(使用 Control.BeginInvoke/Invoke 或 BackgroundWorker)。
Application.DoEvents 引入了重新进入的可能性,这可能导致非常难以理解的错误。
【讨论】:
DoEvents 的可能有效使用提供反馈。 stackoverflow.com/questions/45023826/…
Windows 维护一个队列来保存各种事件,例如单击、调整大小、关闭等。当控件响应事件时,所有其他事件都保留在队列中。因此,如果您的应用程序处理按钮单击的时间过长,则应用程序的其余部分将显示为冻结。因此,您的应用程序在为响应事件而执行一些繁重的处理时,可能会出现无响应的情况。虽然理想情况下您应该以异步方式进行大量处理以确保 UI 不会冻结,但一个快速简单的解决方案是定期调用 Application.DoEvents() 以允许将未决事件发送到您的应用程序。
对于好的 Windows 应用程序,最终用户不喜欢任何形式的应用程序在执行较大/重量级操作时冻结。用户总是希望应用程序以响应方式平稳运行,而不是冻结 UI。但在谷歌搜索后,我发现 Application.DoEvents() 不是一个在应用程序中更频繁使用的好习惯,因此最好使用 BackGround Worker Thread 执行长时间运行的任务而不冻结窗口。
如果你实际看一下,你会得到更好的主意。只需复制以下代码并检查应用程序是否放置 Application.DoEvents()。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
For i As Integer = 0 To 1000
System.Threading.Thread.Sleep(100)
ListBox1.Items.Add(i.ToString())
Application.DoEvents()
Next
End Sub
【讨论】:
恕我直言,您更应该永远不要使用它,因为您最终可能会遇到非常意外的行为。 刚刚生成的代码没问题。诸如您正在再次执行您当前所在的事件处理程序之类的事情,因为用户按下了两次键等等。 如果要刷新控件以显示当前进程,则应显式调用该控件的 .Update,而不是调用 Application.DoEvents。
【讨论】: