什么可能导致C++ Builder/Delphi线程和应用程序无法关闭?

Jos*_*ley 2 windows delphi multithreading shutdown c++builder

有一次,在测试期间,我的C++ Builder/Delphi应用程序在后台工作线程中引发了一个未捕获的异常. EurekaLog发现异常并发送了错误报告,正如我预期的那样,一切似乎都没问题.

但是,当我关闭应用程序的主窗口时,某些内容仍在后台运行,因为应用程序仍然列在任务管理器中(并且仍然打开了资源).

我试图通过故意在后台工作线程中引入各种错误来复制这个问题,但我不能.

什么可能导致一个线程和应用程序保持这样运行,即使在主窗口关闭后(并且,可能是,已调用PostQuitMessage)?

如何确保应用程序始终完全关闭?

War*_* P 7

第一条规则是应该编写线程主执行程序方法,以便可以正确地发出信号并关闭它们,第二条规则是你不应该首先关闭应用程序的主线程,然后希望关闭其他线程在他们自己的时间,为了安全起见,你应该发出所有后台线程停止信号,等待关闭完成,然后关闭你的主线程.最小的THREAD示例:

procedure TMyThread.Execute;
begin
   Init;
   while not Terminated do
      OneWorkItem; // inside OneWorkItem, you  ALSO need to check for Terminated
end;
Run Code Online (Sandbox Code Playgroud)

最小的主要形式/主线程示例:

   procedure TMyMainForm.CheckAndShutdown;
   begin
     if FPendingShutdownFlag then 
       if AllBackgroundThreadsTerminated then 
             Self.Close;
   end;
Run Code Online (Sandbox Code Playgroud)

您可以设置FPendingShutdownFlag并从应用程序空闲处理循环调用上面的函数.当用户单击主窗体FormClose时,如果AllBackgroundThreadsT​​erminated返回false,则将CanClose设置为false,然后设置FPendingShutdownFlag := true.

如果你进行无限循环(同时为true),应用程序不会干净地关闭,即使它看起来像你.不知何故,应用程序被终止,并且正在运行的线程可能会突然消失,或者它们可能会死锁或以其他方式失败,因为它们可能正在使用线程2中的资源,而您正忙于在线程1中释放.

您可能有一个或多个故意竞争条件,因为您可能没有编写可执行中断的线程执行方法,或者您可以在确定后台线程是否为之前开始关闭主应用程序线程和VCL及其对象.完全关闭.