为什么我使用 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
永远不会停止。
我正在使用 OmniThreadLibrary 实现用于发送电子邮件的后台管道(请参阅此 SO
代码如下:
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
永远不会停止。