为什么我使用 OmniThreadLibrary Parallel.Pipeline 的应用程序在关闭后继续留在后台 运行?

Why does my application using OmniThreadLibrary Parallel.Pipeline continue remain running in the background after being closed?

我正在使用 OmniThreadLibrary 实现用于发送电子邮件的后台管道(请参阅此 SO )。我注意到在关闭应用程序后,它会在后台继续 运行(在 Windows 任务管理器中看到)。这意味着我的代码在实现 OTL 管道的方式上有问题。你能帮我找出问题所在吗?

代码如下:

unit uEmailQueue;

interface

uses Classes, OtlCommon, OtlCollections, OtlParallel, Windows;

type
  TEmailServer = record
    SMTPHost: String;
    SMTPPort: Integer;
    SMTPUseSSL: Boolean;
    SMTPUserName: String;
    SMTPPassword: String;
    SMTPSenderName: String;
  end;

  TEmailMessage = record
    RecipientEmailAddr: String;
    EmailSubject: String;
    EmailMessage: String;
  end;

  TEmailQueue = class(TObject)
  private
    FEmailServer: TEmailServer;
    FPipeline: IOmniPipeline;
    procedure SendEmailStage(const input, output: IOmniBlockingCollection);
  public
    constructor Create;
    destructor Destroy; override;
    procedure SendEmail(AEmailMessage: TEmailMessage);
  end;

implementation

{ TEmailQueue }

procedure TEmailQueue.SendEmailStage(const input, output: IOmniBlockingCollection);
var
  mailmessage: TOmniValue;
begin
  for mailmessage in input do
  begin
    Beep(3700, 1500); // just some dummy code for now
  end;
end;

constructor TEmailQueue.Create;
begin
  FPipeline := Parallel.pipeline.Stage(SendEmailStage).Run;

end;

destructor TEmailQueue.Destroy;
begin

  inherited;
end;

procedure TEmailQueue.SendEmail(AEmailMessage: TEmailMessage);
begin
  FPipeline.input.Add(TOmniValue.FromRecord(AEmailMessage));

  // FPipeline.input.CompleteAdding;

  // FPipeline.WaitFor(INFINITE);

end;

end.

我像这样初始化并调用上面的class:

在应用程序主窗体的 OnCreate 事件中:

  FEmailQueue := TEmailQueue.Create;

主窗体上的一个按钮在 OnClick 事件中有这个:

var
  em: TEmailMessage;
begin
  FEmailQueue.SendEmail(em);

稍后,我在主窗体的 OnDestroy 事件中像这样释放 class:

  FEmailQueue.Free;

您应该从 TEmailQueue.Destroy 呼叫 FPipeline.input.CompleteAdding。否则,SendEmailStage永远不会停止。