Multithreading 我如何设计一个;“传送带”;使用OmniThreadLibrary执行的操作?

Multithreading 我如何设计一个;“传送带”;使用OmniThreadLibrary执行的操作?,multithreading,delphi,omnithreadlibrary,Multithreading,Delphi,Omnithreadlibrary,我有一个Windows Delphi应用程序,通过通知图标可以访问“开始”和“停止”菜单项。单击“开始”后,我需要执行以下操作(如我看到的实现): ThreadMonitor:第一个线程正在等待指定文件夹中指定文件的出现 ThreadParse:文件出现后,应将其传输到另一个线程(用于解析内容),并继续监视下一个文件 ThreadDB:解析完所有数据后,将其保存到MySQL数据库中。(另一个具有活动DB连接的后台线程?) ThreadLog:如果步骤1-3中有任何错误,请将其写入日志文件(另一个

我有一个Windows Delphi应用程序,通过通知图标可以访问“开始”和“停止”菜单项。单击“开始”后,我需要执行以下操作(如我看到的实现):

  • ThreadMonitor:第一个线程正在等待指定文件夹中指定文件的出现

  • ThreadParse:文件出现后,应将其传输到另一个线程(用于解析内容),并继续监视下一个文件

  • ThreadDB:解析完所有数据后,将其保存到MySQL数据库中。(另一个具有活动DB连接的后台线程?)

  • ThreadLog:如果步骤1-3中有任何错误,请将其写入日志文件(另一个后台线程?),而不中断步骤1-3

  • 也就是说,原来是一种类似连续输送机的东西,它的工作只需按Stop键即可停止。
    从OmniThreadLibrary的各种方法中我应该使用什么呢?

    最好用于日志记录和数据处理。下面是解决方案的示意图(已编译,但尚未完全实现):


    最好将其用于日志记录和数据处理。下面是解决方案的示意图(已编译,但尚未完全实现):


    下周我会在办公室试试,谢谢你的解释!为什么使用FLogger:=Parallel.BackgroundWorker.NumTasks(1).Execute(Asy_LogMessage).Execute;而不是FLogger:=Parallel.BackgroundWorker.NumTasks(1).Execute(Asy_LogMessage).OnRequestDone(HandleRequestDone)?因为当请求“完成”时没有什么事情可做。请求转到记录消息的工作程序,而无需通知调用者消息已被记录。第二次调用Execute in
    FLogger:=Parallel.BackgroundWorker.NumTasks(1).Execute(Asy_LogMessage).Execute
    这可能是错误吗?是的,对不起,Execute(Asy_LogMessage)应该足够了。我会更正答案。下周我会在办公室试试,谢谢你的解释!为什么使用FLogger:=Parallel.BackgroundWorker.NumTasks(1).Execute(Asy_LogMessage).Execute;而不是FLogger:=Parallel.BackgroundWorker.NumTasks(1).Execute(Asy_LogMessage).OnRequestDone(HandleRequestDone)?因为当请求“完成”时没有什么事情可做。请求转到记录消息的工作程序,而无需通知调用者消息已被记录。第二次调用Execute in
    FLogger:=Parallel.BackgroundWorker.NumTasks(1).Execute(Asy_LogMessage).Execute
    这可能是错误吗?是的,对不起,Execute(Asy_LogMessage)应该足够了。我会更正答案的。
    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.