为什么使用OmniThreadLibrary Parallel.Pipeline的应用程序在关闭后仍继续在后台运行? [英] Why does my application using OmniThreadLibrary Parallel.Pipeline continue remain running in the background after being closed?

查看:104
本文介绍了为什么使用OmniThreadLibrary Parallel.Pipeline的应用程序在关闭后仍继续在后台运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using OmniThreadLibrary to implement a background pipleline for sending emails (refer to this SO question). I notice that after closing the application, it continues running in the background (seen in Windows Task Manager). That means that there is something wrong in my code in the way I implemented the OTL pipeline. Can you help me identify the trouble?

代码如下:

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.

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

I initialize and call the above class like this:

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

In the application's main form's OnCreate event:

  FEmailQueue := TEmailQueue.Create;

主窗体上的按钮在OnClick事件中具有此按钮:

A button on the main form has this in the OnClick event:

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

后来,我在主窗体的OnDestroy事件中释放了这样的类:

later, I free the class like this in the main form's OnDestroy event:

  FEmailQueue.Free;

推荐答案

您应从TEmailQueue.Destroy调用FPipeline.input.CompleteAdding.否则,SendEmailStage将永远不会停止.

You should call FPipeline.input.CompleteAdding from TEmailQueue.Destroy. Otherwise, SendEmailStage will never stop.

这篇关于为什么使用OmniThreadLibrary Parallel.Pipeline的应用程序在关闭后仍继续在后台运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆