我正在使用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');


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)工作线程永远不会触发。我应该如何使我的Worker线程正常工作! :)

问候,
克莱门特

最佳答案

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

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

因此,我认为您需要将“主线程”将任务注入(inject)其中的任务请求队列。

池的想法是它们自己进行管理!您不应该与特定的工作线程进行通信,您应该向其中发送工作请求,然后让池根据需要生成/杀死工作线程。

如果您需要每个特定线程的反馈,我宁愿将TForm.Handle或TOmniMonitor指针包含在任务请求记录中,并让工作线程进行回调并与表单进行通信,而不是from与该线程进行通信

10-07 19:03
查看更多