1

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.

上記のクラスを次のように初期化して呼び出します。

アプリケーションのメイン フォームの OnCreate イベントで:

  FEmailQueue := TEmailQueue.Create;

メイン フォームのボタンの OnClick イベントには次のようなものがあります。

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

後で、メイン フォームの OnDestroy イベントで次のようにクラスを解放します。

  FEmailQueue.Free;
4

1 に答える 1

3

FPipeline.input.CompleteAddingから電話する必要がありますTEmailQueue.Destroy。そうでなければ、SendEmailStage決して停止しません。

于 2015-06-12T17:30:57.097 に答える