【问题标题】:how to avoid "Not Responding" [duplicate]如何避免“不响应” [重复]
【发布时间】:2011-01-19 08:03:42
【问题描述】:

可能重复:
Keep app responsive during long task

在处理大型查询或长流程循环时如何避免“无响应”?

谢谢

【问题讨论】:

    标签: delphi delphi-7


    【解决方案1】:

    在单独的线程中执行它。 (参见 TThread 类)

    【讨论】:

      【解决方案2】:

      永远不要使用Application.ProcessMessages,它会打开一罐蠕虫。
      真的。
      让我重复一遍:不要使用Application.ProcessMessages
      This is why:它要求您的所有消息始终是可重入的。
      您的消息传递,更重要的是您使用的库中的消息传递(您无法确定它是可重入的那种)。
      现在和未来。
      即使在您尚未测试的情况下,或您尚未看到的使用模式。

      你应该做多线程。
      你真的应该。
      使您的同步正确可能需要一些时间,但使用像 backgroundworker 这样的东西可以以一种简洁的方式封装大部分内容。

      如果你不能做多线程,那么你可以cheat
      但你不应该作弊。

      作弊就是推迟真正的解决方案。
      推迟比现在做的成本更高。

      这一切都与upstream decisions and downstream costs有关。
      以后再修正一个错误的决定比现在做出正确的决定并投入一些时间来做正确的决定要昂贵得多。

      编辑:

      使用辅助消息循环的唯一例外是在显示模式表单或对话框时。由于模态的原因,次要消息循环对这些消息的范围有限。

      编辑 2:

      该模式导致所有其他形式被自动禁用;但是,计时器和其他非 UI 消息仍在处理中,因此仍可能发生重新进入。

      --杰罗恩

      【讨论】:

      • 这种针对Application.ProcessMessages 的咆哮有点令人厌烦。如果代码不可重入,则运行辅助消息循环只会出现问题,但这本身就是一个有价值的属性。简单地将代码移动到工作线程可能会产生与Application.ProcessMessages 完全相同的问题,必须确保无法重新输入任何不安全的代码路径。因为工作线程仍在运行而需要禁用按钮与因为调用的代码包含Application.ProcessMessages 而必须这样做没有区别。
      • @Jeroen 我靠一个可以毫无问题地调用Application.ProcessMessages 的程序谋生,所以它可以完成。但是,是的,线程更好。
      • @mghie:我同意两者都需要相当多的努力才能做到正确。自己被这两个咬过,线程的伤痕比Application.ProcessMessages少,因为它更容易屏蔽线程的副作用,消息处理咬我,因为其他人的代码适得其反(有一个用户仍然可以执行操作的漏洞)。也许其他人有不同的经历,但要正确传达信息很困难,因为它更难控制。
      • 只是为了投反对票 Application.ProcessMessages:我正在使用 FastReports,它是一个不错的报告框架,但作者有一个绝妙的主意,可以从报告引擎调用 Application.ProcessMessages。这绝对是丑陋的:如果出于任何原因报告需要超过一秒钟才能显示,用户可以再次按下Print 按钮。并且遵循电梯最佳实践,他们可能会多次按下按钮,只是为了确定。对此进行屏蔽需要大量不必要的工作!
      • Jeroen : 请为此写一篇博文!!!
      【解决方案3】:

      在我看来,您有两个选择(取决于任务(或循环)需要多长时间):

      • 使用 Alexander Malakhov 提到的线程;
      • 在每次循环完成后添加 Application.ProcessMessages(强制应用程序绘制 UI 并响应事件,但当循环花费大量时间时效果不佳 - 使用线程..)如果您希望应用程序完成响应,但是我建议它仅用于 - 少量时间循环,对于长时间密集循环使用线程。

      【讨论】:

      • 不,不,不,不!不要使用 Application.Process 消息;它有太多的副作用 (forums.embarcadero.com/message.jspa?messageID=56704#56704) 并且要求所有消息处理始终是可重入的。不仅是您的消息处理。所有消息处理,在您的应用程序中的任何地方,现在和将来。不要!
      • +1 是的 Jeroen,但如果他是初学者,这将帮助他(希望)了解线程的真正价值,如果他不是初学者,那么他已经知道,无论如何,你是对的,但为了他的目的,它可能会奏效。
      • 这就是我在回答中建议使用后台工作人员的原因。它使多线程生活变得更加轻松。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-15
      • 1970-01-01
      • 2021-08-17
      • 2015-09-12
      • 1970-01-01
      • 2014-07-06
      相关资源
      最近更新 更多