匿名线程不允许应用程序关闭

Anonymous Thread not letting application close

我有一个应用程序,用户可以通过交互方式或从命令行运行。在第二种模式下,程序必须在完成后退出。

这是基本的最小代码。似乎 application.terminated 从未设置过;

如何关闭此程序,w/o0 用户交互。

unit Unit4;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls ;

type
  TForm4 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    procedure DoSomeStuff;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

implementation

{$R *.dfm}

procedure TForm4.Button1Click(Sender: TObject);
var
  anonThread : TThread;
begin
   anonThread := TThread.CreateAnonymousThread(procedure
   begin
     while not application.terminated do
     begin
       doSomeStuff;
    end;
   end);
   anonThread.Start;

end;

procedure TForm4.DoSomeStuff;
var
  i : integer;
begin
  for i := 0 to 10 do
    begin
      beep;
      sleep(100);
    end;
    application.Terminate;
end;


end.

Application.Terminated 属性 在 Application.Run() 中没有消息循环(或者至少是调用 Application.ProcessMessages() 的手动循环)时无法工作 UI 线程。这是因为 Application.Terminate() 只是将 WM_QUIT 消息发送到调用线程的消息队列。 Application.Terminated 在处理该消息之前不会设置。控制台应用程序通常不会调用 Application.Run(),因此 Application.Terminated 不适用于控制台应用程序。

您应该重新设计您的代码以删除对 Application 和您在控制台模式下的 TForm 的依赖,例如:

program MyApp;

uses
  MyWorkUnit, Unit4;

begin
  if IsRunInCommandLineMode then
  begin
    DoSomeStuff;
  end else
  begin
    Application.Initialize;
    Application.CreateForm(TForm4, Form4)
    Application.Run;
  end;

end.

unit MyWorkUnit;

interface

procedure DoSomeStuff;

implementation

procedure DoSomeStuff;
var
  i : Integer;
begin
  for i := 0 to 10 do
  begin
    Beep;
    Sleep(100);
  end;
end;

end.

unit Unit4;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm4 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

implementation

{$R *.dfm}

uses
  MyWorkUnit;

procedure TForm4.Button1Click(Sender: TObject);
begin
   TThread.CreateAnonymousThread(
      procedure
      begin
        while not Application.Terminated do
          DoSomeStuff;
      end
    ).Start;    
end;

end.