Dan*_*all 6 delphi multithreading indy terminate
我们的程序在程序开头创建一个后台线程.后台线程使用Indy进行一些数据库完整性检查并检查Internet中的内容.10秒后,后台线程应该完成,因为FreeOnTerminate为true,它也会自行清理.
我们注意到,在某些情况下,如果用户过快地关闭程序,则该过程仍然有效,直到后台线程完成.
由于我们无法完全重现该问题,因此我创建了一个演示项目来尝试一些事情:
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;
Run Code Online (Sandbox Code Playgroud)
结果有点令我惊讶:关闭MainForm后,进程将立即终止,后台线程将被硬杀死.
现在我有几个问题:
关闭MainForm(=主线程的退出)后,我应该通过.Terminate手动终止所有创建的线程还是自动完成?
我的线程只能检查Self.Terminated还是应该检查Application.Terminated?
当我关闭应用程序时,为什么上面显示的繁忙线程会立即被杀死?我期望Project1.exe进程将运行,直到所有线程都由他们自己完成.(并且如上所述,我们已经看到了一个主窗体关闭的应用程序,但是一个线程阻止了关闭过程).
那么,由于运行后台线程,我们的实际应用程序的进程是如何终止的呢?可能它与互联网的东西有关,这可能导致应用程序等到达到连接超时?
关闭主窗体并不等同于退出主线程。表单关闭后代码继续运行。特别是,单位已经最终确定。
如果您处理测试线程的OnTerminate事件,或者在方法中放置断点Terminate,您将看到程序退出时不会自动调用它。你必须自己调用它。但还要注意,线程不会仅仅因为Terminate被调用而停止运行。它会继续运行,直到自行停止或被强制终止。调用WaitFor以等待其终止。
不用费心去检查Application.Terminated;线程的属性应该足够了。
当程序退出时,您的线程会被强制终止,因为最终您的程序会调用ExitProcess,而操作系统所做的事情之一就是终止所有其他线程。它不会调用Terminate它们,因为操作系统不知道 Delphi 类和方法。
您必须进行更多调试,以确定为什么您的程序没有为您的客户立即终止。您说您无法在内部重现该问题,并且您编写的测试程序也没有表现出该问题。您必须找到愿意配合您进一步调试工作的客户。你真的知道这是支撑事情的线索,还是到目前为止这只是一个猜测?