后台线程什么时候阻止进程被终止? [英] When does background threads prevent the process of being terminated?

查看:183
本文介绍了后台线程什么时候阻止进程被终止?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的程序在程序开始时创建一个后台线程。后台线程使用Indy对Internet中的内容进行一些数据库完整性检查和检查。 10秒钟后,后台线程应该完成,因为FreeOnTerminate是true,它也将自动清理。

Our program creates a background thread at the beginning of the program. The background thread does some database integrity checks and checks for stuff in the Internet using Indy. After 10 seconds, the background thread should be finished and since FreeOnTerminate is true, it will also clean itself up.

我们注意到,在某些情况下,如果用户关闭程序太快了,这个过程将仍然存在,直到后台线程完成。

We have noticed that in some cases, if the user closes the program too quickly, the process will still be alive until the background thread is finished.

由于我们无法准确复制问题,我已经创建了一个演示项目尝试一些东西:

Since we couldn't exactly reproduce the issue, I have created a demo project to try a few things:

type
  TBackgroundThread = class(TThread)
  protected
    procedure Execute; override;
  end;

{ TForm1 }

var
  bt: TBackgroundThread;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: integer;
begin
  // Create a background thread which runs X seconds and then terminates itself.
  bt := TBackgroundThread.Create(false);
  bt.FreeOnTerminate := true;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  // The user closes the app while the background thread is still active
  Sleep(2000);
  Close;
end;

{ TBackgroundThread }

procedure TBackgroundThread.Execute;
var
  i: integer;
  x: cardinal;
begin
  inherited;

  // Simulate some work that the background thread does
  x := MaxInt;
  for i := 0 to MaxInt do
  begin
    x := Random(x);
  end;
end;

结果对我来说有点令人惊讶:关闭MainForm后,该过程将立即终止并且后台线程将被严重杀死。

The result is a bit surprising to me: After I close the MainForm, the process will be immediately terminated and the background thread will get hard-killed.

现在我有一些关于这个问题:

Now I have a few questions about this:


  1. 在MainForm(=主线程退出)结束后,应该通过.Terminate手动终止所有创建的线程,还是自动完成?

  1. After the closing of the MainForm (= exit of the main thread), should I manually terminate all created threads via .Terminate or will that be done automatically?

我的线程只检查Self.Terminated,还是应该检查Application.Terminated?

Shall my threads only check for Self.Terminated or should they also check for Application.Terminated ?

为什么我的忙如上图所示的线程在关闭应用程序时立即死机?我预计Project1.exe的进程将运行,直到所有的线程都完成。 (并且如上所述,我们已经看到一个主窗体关闭的应用程序,但一个线程正在阻止被关闭的过程)。

Why does my busy thread as shown above gets immediately killed when I close the application? I expected that the process Project1.exe will run until all threads have finished by themselfes. (And as described above, we had seen an application where the main form is closed, but a thread is preventing the process of being closed).

那么可能的是,由于运行的后台线程,我们的真实应用程序的进程并没有终止?可能它与互联网的东西有关,这可能会导致应用程序等到达到连接超时?

How is it possible then, that our real application's process does not terminate because of a running background thread? Might it have something to do with the Internet stuff, which might cause the app to wait until a connection timeout is reached?


推荐答案

关闭主窗体与退出主线程不同义。代码在表单关闭后继续运行。特别是单位被定稿。

Closing the main form is not synonymous with exiting the main thread. Code continues to run after the form is closed. In particular, units are finalized.

如果您处理测试线程的 OnTerminate 事件,或者在终止方法,您将看到在程序退出时它不会自动调用。你必须自己打电话。但是请注意,线程不会因为 Terminate 被调用而停止运行。它继续运行,直到它停止自己或它被强制终止。调用 WaitFor 等待它终止。

If you handle your test thread's OnTerminate event, or put a breakpoint in the Terminate method, you'll see that it's not called automatically when your program exits. You'll have to call it yourself. But note also that a thread doesn't stop running just because Terminate is called. It continues running until it stops itself or it's terminated forcefully. Call WaitFor to wait for it to terminate.

不要打扰检查应用程序。终止;线程的属性应该是足够的。

Don't bother checking Application.Terminated; the thread's property should be sufficient.

您的线程在程序退出时被强制终止,因为最终您的程序调用 ExitProcess ,并且操作系统所做的一件事情是终止所有其他线程。它不调用终止,因为操作系统不了解Delphi类和方法。

Your thread gets terminated forcefully as your program exits because eventually your program calls ExitProcess, and one of the things the OS does there is to terminate all other threads. It doesn't call Terminate on them because the OS doesn't know about Delphi classes and methods.

你我们必须做一些更多的调试,以确定您的程序为什么不能及时终止您的客户。你说你不能在内部重现这个问题,而且你也编写了一个没有出现问题的测试程序。您将不得不找到一个将与您进一步调试工作配合的客户。你真的知道这是持有东西的线程,还是只是一个猜测到目前为止?

You'll have to do some more debugging to determine why your program doesn't terminate promptly for your customers. You say you can't reproduce the problem in house, and you've written a test program that doesn't exhibit the problem, either. You'll have to find a customer who will cooperate with your further debugging efforts. Do you really know it's the thread that's holding things up, or is that just a guess so far?

这篇关于后台线程什么时候阻止进程被终止?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆