Windows – 如何使用DoEvents()而不是“邪恶”?

前端之家收集整理的这篇文章主要介绍了Windows – 如何使用DoEvents()而不是“邪恶”?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
一个简单的 search for DoEvents带来了很多结果,基本上是:

DoEvents is evil. Don’t use it. Use threading instead.

一般引用的原因是:

重新入侵问题
>表现不佳
>可用性问题(例如拖放到禁用的窗口上)

但是一些值得注意的Win32功能(如TrackPopupMenu和DoDragDrop)执行自己的消息处理来保持UI的响应,就像DoEvents一样。
然而,这些似乎都没有遇到这些问题(表现,重新入侵等)。

他们是如何做到的呢?他们如何避免DoEvents引用的问题? (还是他们?)

DoEvents()是危险的。但我敢打赌你每天做很多危险的事情。就在昨天,我引出了一些爆炸装置(未来读者:请注意相对于某个美国假期的原始发布日期)。小心,我们有时会考虑到危险。当然,这意味着知道和理解危险是什么:

>再入场问题。这里有两个危险:

>这里的一部分问题与调用堆栈有关。如果您在循环中调用.DoEvents()来处理使用DoEvents()的消息等等,那么您将获得一个非常深入的调用堆栈。过多使用DoEvents()很容易,并且意外填满您的调用堆栈,从而导致StackOverflow异常。如果你只在一两个地方使用.DoEvents(),你可能还好。如果这是您长时间运行的过程中遇到的第一个工具,您可以在这里轻松找到自己的麻烦。即使一个用在错误的地方也可以使用户强制执行一个stackoverflow异常(有时只需按住Enter键),这可能是一个安全问题。
>有时可以在调用堆栈上找到相同的方法两次。如果你没有建立这个方法(提示:你可能没有),那么糟糕的事情就会发生。如果传入方法的所有内容都是一个值类型,并且不依赖于该方法之外的内容,那么您可能会很好。但是否则,您需要仔细考虑如果在调用.DoEvents()的时候返回给控件之前,如果整个方法要再次运行,会发生什么。您的方法之外的哪些参数或资源可能会被修改,您没有想到?您的方法是否更改任何对象,堆栈中的两个实例可能在同一对象上执行?

>性能问题。 DoEvents()可以给出多线程的错觉,但它不是真正的mutlithreading。这至少有三个真正的危险:

>当您调用DoEvents()时,您可以将现有线程控制回消息泵。消息泵可能反过来控制别的东西,还有一些可能需要一些时间。结果是,您的原始操作可能需要更长的时间才能完成,如果它在一个线程本身,从来没有产生控制,绝对比它需要更长的时间。
>复制工作。既然可以找到自己运行相同的方法两次,而且我们已经知道这个方法是昂贵的/长时间运行的(或者你不需要DoEvents()),即使你考虑了所有的外部依赖关系以上所以没有不利的副作用,你可能还是重复了很多工作。
>另一个问题是极限版本的第一个:潜在的僵局。如果您的程序中的其他内容取决于进程的完成,并且将阻止它,直到它被DoEvents()的消息泵调用,您的应用程序将被卡住并变得无响应。这可能听起来很牵强,但在实践中,意外地很容易做到,而且以后很难找到和调试崩溃。这是您可能在自己的计算机上遇到的一些挂起的应用程序的根源。

>可用性问题。这些是由于不妥善处理其他危险而产生的副作用。只要您在其他地方看到适当的地方,这里没有什么新鲜事。

如果你能确定你是所有这些事情的话,那就去吧。但是,如果DoEvents()是第一个解决UI响应/更新问题的地方,那么您可能不会正确地解释所有这些问题。如果不是你看的第一个地方,还有足够的其他选项,我会质疑你如何使用它来考虑DoEvents()。

现实情况是,大多数时候,至少在.Net世界里,一个BackgroundWorker的组件几乎是一样简单,至少一旦你完成了一两次,它将以安全的方式完成这项工作。

原文链接:https://www.f2er.com/windows/372568.html

猜你在找的Windows相关文章