【问题标题】:Why does my application using OmniThreadLibrary Parallel.Pipeline continue remain running in the background after being closed?为什么我使用 OmniThreadLibrary Parallel.Pipeline 的应用程序在关闭后仍继续在后台运行?
【发布时间】:2015-06-12 16:59:56
【问题描述】:

我正在使用 OmniThreadLibrary 实现用于发送电子邮件的后台管道(请参阅此 SO question)。我注意到关闭应用程序后,它继续在后台运行(在 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.

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

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

  FEmailQueue := TEmailQueue.Create;

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

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

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

  FEmailQueue.Free;

【问题讨论】:

  • procedure TEmailQueue.SendEmail(AEmailMessage: TEmailMessage); 我敢打赌这效率不高,我认为您最好将 A EmailMessage 设置为 const 参数或 var 参数。
  • @Arioch'The 可能。如果将其设为 const,那么它(也)是否会防止在内存中创建重复的字符串(如 var),从而更快?
  • 不,字符串(TurboPascal 的 ShortString[nnn] 类型和 MS-COM WideString 类型除外)如接口和 dyn-array 是引用计数类型,因此在复制 @987654328 时不应复制字符串本身@
  • OTOH,XE1 后的 Delphi 已损坏 w.r.t。字符串,所以如果 const'ing 参数会节省更多的东西,而不仅仅是复制指针和调用一些原子增量kazav.blogspot.ru/2014/01/delphi-2.html

标签: multithreading delphi delphi-xe7 omnithreadlibrary


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-02
    • 2021-05-17
    • 1970-01-01
    • 2021-04-20
    • 1970-01-01
    • 2019-07-18
    • 2014-07-01
    • 1970-01-01
    相关资源
    最近更新 更多