一个简单的searchDoEvents
带来了很多的结果,基本上,导致:
DoEvents
是邪恶的。 不要使用它。 使用线程代替。
一般引用的原因是:
但是一些值得注意的Win32函数(如TrackPopupMenu
和DoDragDrop
执行自己的消息处理以保持UI的响应,就像DoEvents
一样。
但是,这些问题似乎都没有遇到这些问题(performance,重新入侵等)。
他们是如何做到的呢? 他们如何避免DoEvents
引用的问题? (或者他们?)
DoEvents()是危险的 。 但是我敢打赌,你每天都会做很多危险的事情。 就在昨天,我掀起了一些爆炸性的装置(未来的读者:注意相对于美国某个节日的原始发布date)。 我们谨慎处理,有时可以解决危险。 当然,这意味着了解和理解危险是什么:
再入境问题。 其实有两个危险:
性能问题。 DoEvents()可以给出multithreading的错觉 ,但它不是真正的multithreading。 这至less有三个实际的危险:
可用性问题。 这些是由于没有适当考虑其他危险而产生的副作用。 这里没有什么新东西,只要你在其他地方适当地看。
如果你能确定你占了所有这些东西,那就继续吧。 但实际上,如果DoEvents()是您想要解决UI响应/更新问题的第一个地方,那么您可能没有正确解决所有这些问题。 如果这不是你看的第一个地方,还有其他的select,我会质疑你是如何考虑DoEvents()的。
实际情况是,大多数情况下,至less在.Net的世界里,一个BackgroundWorker组件几乎一样容易,至less一旦你完成了一次或两次,它将以安全的方式完成这项工作。 最近,asynchronous/等待模式可以更加有效和安全。
回到16位Windows时代,当每个任务共享一个线程时,在一个紧密的循环中保持程序响应的唯一方法是DoEvents
。 正是这种非模态的使用被劝阻于线程。 这是一个典型的例子:
' Process image For y = 1 To height For x = 1 to width ProcessPixel x, y End For DoEvents ' <-- DON'T DO THIS -- just put the whole loop in another thread End For
对于模态的东西(比如跟踪一个popup窗口),它可能还是可以的。
我可能是错的,但在我看来, DoDragDrop
和TrackPopupMenu
是比较特殊的情况,因为他们接pipe了UI,所以没有重入问题(我认为这是人们将DoEvents
描述为“Evil”的主要原因) )。
就我个人而言,我认为将这个function解读为“邪恶”并不是很有帮助,而只是解释一下让人们自己决定的缺陷。 在DoEvents
的情况下,在极less数情况下仍然可以使用它,例如当显示模态进度对话框时,用户不能与其余的UI进行交互,因此不存在重入问题。
当然,如果说“邪恶”是指“如果没有充分理解陷阱,就不应该使用”,那么我认为DoEvents
是邪恶的。