Delphi - OTL - 线程池和工作线程之间的通信

3
我正在使用XE8,并尝试构建一个真实应用程序的示例。
我需要在主“服务线程”和OTL线程池之间进行通信。 这些示例都设置了表单和监视器,但我不需要它们,但我无法想出一种编写干净代码的方法。到目前为止,这是我所做的:
TProcessWorker = Class( TOmniWorker )
strict private
  FTaskID : int64;
  FIndex : Integer;
  FFolder : String;
protected
  function Initialize: Boolean; override;
public
  procedure WriteTask( var msg : TMessage); message _AM_WriteTask;
End;

{ TProcessWorker }

function TProcessWorker.Initialize: Boolean;
begin
  FTaskID := Task.UniqueID;
  FIndex := 0;
  result := True;
  FFolder := Format('%s/%d', [Task.Param['Folder'].AsString, FTaskID]);
  ForceDirectories(FFolder);
end;

实现方式:

procedure TProcessWorker.WriteTask(var msg: TMessage);
var
  ps : PString;
  L : TStringStream;
begin
   Ps:= PString(msg.LParam);
   L := TStringStream.Create( ps^ );
   try
     L.SaveToFile( format('%s\%d.txt',[FFolder, fIndex]) );
   finally
     l.Free;
     inc(FIndex);
   end;
end;

在主线程中,为了创建线程池,我正在调用以下代码:
FThreadPool := CreateThreadPool('Thread pool test');

and

var
  lFolder : String;
  Process : IOmniWorker;
begin
   lFOlder := ExtractFilePath(ParamStr(0));
   Process := TProcessWorker.Create;
   CreateTask( Process, 'Task test').Unobserved.SetParameter('Folder',lFolder).Schedule(FThreadPool);

我不知道如何正确地调用我的工作线程。在我的实际应用中,将触发多个线程,我需要确保正确使用线程池。

1)通过像我这样调用CreateTask,我如何正确使用线程池?对于我需要的每个进程都调用CreateTask似乎很奇怪。

2)工作线程从未触发。我该如何让我的工作线程工作!:)

问候, Clément

2个回答

1

OmniThreadLibrary测试08_RegisterComm展示了如何在两个线程之间直接通信。

基本上,您需要创建一个IOmniTwoWayChannel实例,并在工作线程的Initialize方法中使用Task.RegisterComm(<channel>)注册其端点。

然后,您可以以“正常”的方式发送消息,使用<channel>.Send(<message>, <data>),如果您按Delphi方式装饰它,则这些消息将被分派到其他任务的消息方法中:

procedure MessageHandler(var msg: TOmniMessage); message <message>;

0

检查http://otl.17slon.com/book/doku.php?id=book:howto:connectionpool

我的感觉是OTL基于数据容器,而不是线程。

所以我认为你需要创建一个任务请求队列,让你的“主线程”注入任务。

池的概念是它们自己管理!你不应该与特定的工作线程通信,你只需将工作请求发送到其中,然后让池根据需要生成/杀死工作线程。

如果你需要从每个特定的线程获得反馈,我宁愿将TForm.Handle或可能是TOmniMonitor指针包含在任务请求记录中,并使工作线程回调并与表单通信,而不是从表单到线程。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接