1

通知アイコンからアクセスできる「開始」および「停止」メニュー項目を持つ Windows Delphi アプリケーションがあります。[開始] をクリックした後、次のことを行う必要があります (実装を参照)。

  1. ThreadMonitor : 最初のスレッドは、指定されたフォルダーに指定されたファイルが表示されるのを待機しています。

  2. ThreadParse : ファイルが表示されたら、(コンテンツを解析するために) 別のスレッドに転送し、次のファイルの監視を続行する必要があります。

  3. ThreadDB : すべてのデータが解析されたら、それらを MySQL DB に保存します。(アクティブな DB 接続を持つ別のバックグラウンド スレッド?)

  4. ThreadLog : 手順 1 ~ 3 でエラーが発生した場合は、手順 1 ~ 3 を中断せずにログ ファイル (別のバックグラウンド スレッド?) にエラーを書き込みます。

つまり、停止を押すだけで作業が停止する連続コンベアのようなものであることがわかりました。OmniThreadLibrary のさまざまなメソッドから何を使用すればよいですか?

4

1 に答える 1

5

おそらく、ログにはParallel.BackgroundWorkerを使用し、データ処理にはParallel.Pipelineを使用するのが最善でしょう。ソリューションのスケッチを次に示します (コンパイルされますが、完全には実装されていません)。

unit PipelineDemo1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
  OtlCommon, OtlCollections, OtlParallel;

type
  TfrmPipelineDemo = class(TForm)
    btnStart: TButton;
    btnStop: TButton;
    procedure btnStartClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
  private
    FLogger  : IOmniBackgroundWorker;
    FPipeline: IOmniPipeline;
  strict protected //asynchronous workers
    procedure Asy_LogMessage(const workItem: IOmniWorkItem);
    procedure Asy_Monitor(const input, output: IOmniBlockingCollection);
    procedure Asy_Parser(const input: TOmniValue; var output: TOmniValue);
    procedure Asy_SQL(const input, output: IOmniBlockingCollection);
  public
  end;

var
  frmPipelineDemo: TfrmPipelineDemo;

implementation

uses
  OtlTask;

{$R *.dfm}

procedure TfrmPipelineDemo.Asy_LogMessage(const workItem: IOmniWorkItem);
begin
  //log workItem.Data
end;

procedure TfrmPipelineDemo.Asy_Monitor(const input, output: IOmniBlockingCollection);
begin
  while not input.IsCompleted do begin
    if FileExists('0.0') then
      output.TryAdd('0.0');
    Sleep(1000);
  end;
end;

procedure TfrmPipelineDemo.Asy_Parser(const input: TOmniValue; var output: TOmniValue);
begin
  // output := ParseFile(input)
  FLogger.Schedule(FLogger.CreateWorkItem('File processed: ' + input.AsString));
end;

procedure TfrmPipelineDemo.Asy_SQL(const input, output: IOmniBlockingCollection);
var
  value: TOmniValue;
begin
  //initialize DB connection
  for value in input do begin
    //store value into database
  end;
  //close DB connection
end;

procedure TfrmPipelineDemo.btnStartClick(Sender: TObject);
begin
  FLogger := Parallel.BackgroundWorker.NumTasks(1).Execute(Asy_LogMessage);

  FPipeline := Parallel.Pipeline
    .Stage(Asy_Monitor)
    .Stage(Asy_Parser)
    .Stage(Asy_SQL)
    .Run;
end;

procedure TfrmPipelineDemo.btnStopClick(Sender: TObject);
begin
  FPipeline.Input.CompleteAdding;
  FPipeline := nil;
  FLogger.Terminate(INFINITE);
  FLogger := nil;
end;

end.
于 2015-03-20T16:11:12.243 に答える