gpt4 book ai didi

windows - 如何在没有 "evil"的情况下使用 DoEvents() ?

转载 作者:可可西里 更新时间:2023-11-01 12:14:17 26 4
gpt4 key购买 nike

一个简单的search for DoEvents 带来了很多结果,基本上,导致:

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



一般引用的原因是:
  • 重入问题
  • 性能不佳
  • 可用性问题(例如在禁用的窗口上拖/放)

  • 但是一些值得注意的 Win32 函数,例如 TrackPopupMenuDoDragDrop执行自己的消息处理以保持 UI 响应,就像 DoEvents做。
    然而,这些似乎都没有遇到这些问题(性能、重入等)。

    他们是怎么做到的呢?他们如何避免 DoEvents 引用的问题? (或者他们是?)

    最佳答案

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

  • 再入境问题。 这里实际上有两个危险:
  • 这里的部分问题与调用堆栈有关。如果您在循环中调用 .DoEvents(),该循环本身处理使用 DoEvents() 的消息,依此类推,您将获得一个非常深的调用堆栈。很容易过度使用 DoEvents() 并意外填满您的调用堆栈,从而导致 StackOverflow 异常。如果你只在一两个地方使用 .DoEvents() ,你可能没问题。如果它是您在长时间运行的过程中使用的第一个工具,那么您很容易在这里遇到麻烦。即使在错误的地方使用一次,也可能使用户强制出现 stackoverflow 异常(有时只需按住 Enter 键即可),这可能是一个安全问题。
  • 有时可能会在调用堆栈上两次找到相同的方法。如果您没有考虑到这一点来构建方法(提示:您可能没有),那么可能会发生不好的事情。如果传递给该方法的所有内容都是值类型,并且不依赖于该方法之外的内容,则可能没问题。但除此之外,您需要仔细考虑如果在调用 .DoEvents() 的地方将控制权返回给您之前再次运行整个方法会发生什么情况。您的方法之外的哪些参数或资源可能会被修改,这是您没有预料到的?您的方法是否更改了任何对象,其中堆栈上的两个实例可能作用于同一个对象?
  • 性能问题。 DoEvents() 可以给人多线程的错觉,但它不是真正的多线程。这至少有三个真正的危险:
  • 当您调用 DoEvents() 时,您将现有线程的控制权交还给消息泵。消息泵可能反过来将控制权交给其他东西,而其他东西可能需要一段时间。结果是您的原始操作可能需要更长的时间才能完成,如果它本身在一个永远不会产生控制的线程中,肯定比它需要的时间更长。
  • 重复工作。由于可能会发现自己两次运行相同的方法,而且我们已经知道这种方法很昂贵/需要长时间运行(或者您一开始就不需要 DoEvents()),即使您考虑了提到的所有外部依赖项以上,所以没有不利的副作用,你可能仍然会重复很多工作。
  • 另一个问题是第一个的极端版本​​:可能会陷入僵局。如果您的程序中的其他内容取决于您的进程完成,并且会阻塞直到它完成,并且该内容由来自 DoEvents() 的消息泵调用,您的应用程序将卡住并变得无响应。这听起来可能有些牵强,但在实践中意外地很容易发生,而且以后很难发现和调试崩溃。这是您在自己的计算机上可能遇到的一些应用程序挂起情况的根源。
  • 可用性问题。 这些是由于没有正确考虑其他危险而导致的副作用。只要您适本地查看其他地方,这里就没有什么新东西了。

  • 你可以确定你已经考虑了所有这些事情,然后继续。但实际上,如果 DoEvents() 是您寻求解决 UI 响应性/更新问题的第一个地方,那么您可能没有正确考虑所有这些问题。如果这不是您首先看到的地方,那么还有足够多的其他选项,我会质疑您是如何考虑 DoEvents() 的。今天,DoEvents() 的存在主要是为了与在其他可用选项之前出现的旧代码兼容,并作为新程序员的拐杖,他们还没有获得足够的经验来接触其他选项。

    现实情况是,在大多数情况下,至少在 .Net 世界中, BackgroundWorker 组件几乎同样简单,至少在您完成一两次之后,它将以安全的方式完成工作。最近, 异步/等待模式 或使用 Task 可以更有效和安全,而无需自己钻研成熟的多线程代码。

    关于windows - 如何在没有 "evil"的情况下使用 DoEvents() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11352301/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com