这是等待 Thread.finalization 并保持应用程序响应的正确方法

发布于 2024-10-02 19:40:39 字数 195 浏览 6 评论 0原文

实际上我正在使用这段代码并且工作正常,但我想知道这是否是正确的方法。

  while WaitForSingleObject(MyThread.Handle, 0) = WAIT_TIMEOUT do
    Application.ProcessMessages;

  ShowMessage('i am done');

Actually i am using this code and works ok, but i 'am wondering if is the correct way.

  while WaitForSingleObject(MyThread.Handle, 0) = WAIT_TIMEOUT do
    Application.ProcessMessages;

  ShowMessage('i am done');

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

血之狂魔 2024-10-09 19:40:39

VCL TThread 类有自己的 WaitFor() 方法,当在主线程上下文中调用时,该方法会在内部泵送主消息队列:

MyThread.WaitFor; 
ShowMessage('i am done'); 

The VCL TThread class has its own WaitFor() method that pumps the main message queue internally when called within the main thread context:

MyThread.WaitFor; 
ShowMessage('i am done'); 
梦萦几度 2024-10-09 19:40:39

调用 Application.ProcessMessages 通常被认为是代码异味。如果主线程无事可做,则让其空闲。

如果你经营一家公司,需要一名员工跑到商店去拿一些急需的物资,你会在门口踱步直到他回来,还是愿意坐在办公室里休息并等待他回来。他,因为你听到他进门而发现补给品在这里?无论哪种方式,他都会花费相同的时间,但第一种方式会让你的腿疲惫不堪。

同样,不要让 UI 监视线程,而是让线程向 UI 报告。实现此目的的一种方法是让线程使用 PostMessage 在完成后将自定义消息发送到启动它的表单,并在表单上放置一个消息处理程序来响应它。

Calling Application.ProcessMessages is generally considered a code smell. Let your main thread idle if it's got nothing to do.

If you ran a company and needed one of your workers to run to the store and grab some much-needed supplies, would you then pace by the door until he got back, or would you prefer to sit in your office and rest and wait for him, and find out that the supplies are here because you hear him walk through the door? Either way, he'll take the same amount of time, but the first way's gonna wear your legs out.

Similarly, instead of having your UI watch the thread, have the thread report back to the UI. One way to do this is to have the thread use PostMessage to send a custom message to the form that launched it once it's finished, and put a message handler on the form to respond to it.

东风软 2024-10-09 19:40:39

它看起来是正确的(如果正确意味着它可以完成工作)。我要改变的是等待多一点时间(50 毫秒看起来很好,可以保持应用程序响应),同时不消耗 CPU。

while WaitForSingleObject(MyThread.Handle, 50) = WAIT_TIMEOUT do
  Application.ProcessMessages;
ShowMessage('i am done');

当然还有其他方法可以做到这一点......<笑话>但我通常应用主要的工程原理之一:

如果它有效,就不要碰它!

It looks correct (if correct means it do the work). What I would change is to wait for a bit more time (50ms looks good to maintain the application responsive) while not eating CPU.

while WaitForSingleObject(MyThread.Handle, 50) = WAIT_TIMEOUT do
  Application.ProcessMessages;
ShowMessage('i am done');

Sure there are other ways to do it... <joke>but I usually apply one of the main engineering principles:

if it works, don't touch it!</joke>

上课铃就是安魂曲 2024-10-09 19:40:39

我同意 Mason Wheeler 的评论,最好让主线程完成其工作,但我建议在线程上使用 OnTerminate 事件。它更加“Delphi 自然”,内部逻辑为您执行 PostMessage 位。由于 TThread 不是组件,因此您无法在对象检查器中查看它,并且必须自己编写并附加事件处理程序。它在线程完成/终止后被调用(在主线程中!)。

I agree with Mason Wheeler's remark, the main thread is best left to do its job, but I would suggest using the OnTerminate event on the thread. It is more 'Delphi natural' and the internal logic does the PostMessage bit for you. Since TThread is not a component, you can't view it in the object inspector and have to write and attach an event handler yourself. It gets called (in the main thread!) after the thread has completed/terminated.

寻梦旅人 2024-10-09 19:40:39

虽然看起来不错,但像 jachguate 我也会使用比 0 更大的超时值。如果您使用 WaitForSingleObject(MyThread.Handle, 100) 那么主线程将等待更长的时间,从而占用更少的 CPU 周期。
不过,更好的解决方案是使用消息。您的应用程序启动线程,然后将所有控件置于禁用模式。然后线程执行,完成后,使用 SendMessage 或 PostMessage 到主窗口通知它线程再次完成。然后您的应用程序将再次启用每个控件(以及其他任何控件)。这样做的优点是,您可以保持应用程序的“自然”消息循环处于活动状态,而不是使用此解决方案运行您自己的消息循环。
不幸的是,消息方法有一个缺点:如果线程崩溃,则不会发送任何消息回来,所以备份计划是可行的。例如,通过向主窗体添加一个计时器控件,每秒检查线程是否仍处于活动状态。如果没有,它也会再次激活表单,再次禁用自身。

While it looks okay, like jachguate I would use a bigger time-out value than 0 too. If you use WaitForSingleObject(MyThread.Handle, 100) then the main thread will wait a bit longer, thus eating up less CPU cycles.
A better solution would be the use of messages, though. Your application starts the thread and then puts all controls in disabled mode. The thread then executes and when it's finished, use SendMessage or PostMessage to the main window to notify it that the thread is done again. Then your application will just enable every control (and whatever else) again. This has as advantage that you keep the "natural" messageloop for the application alive, instead of running your own messageloop with this solution.
Unfortunately, the message-method has one drawback: if the thread crashes then no message will be sent back, so a backup plan would be practical. For example, by adding a timer control to your mainform which checks every second if the thread is still alive. If not, it too would just activate the form again, disabling itself again.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文