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