首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi - OTL - ThreadPool与工作线程之间的通信

Delphi - OTL - ThreadPool与工作线程之间的通信
EN

Stack Overflow用户
提问于 2015-05-27 07:42:23
回答 2查看 960关注 0票数 2

我正在使用XE8,并且正在尝试构建一个真实应用程序的示例。

我需要在主“服务线程”和OTL线程池之间进行通信。示例都是用表单和监视器设置的。我不需要这些,但我想不出一种方法来写一个干净的代码。到目前为止,我是这样做的:

代码语言:javascript
复制
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;

实施方式为:

代码语言:javascript
复制
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;

在主线程中,为了创建池,我调用:

代码语言:javascript
复制
FThreadPool := CreateThreadPool('Thread pool test');

代码语言:javascript
复制
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

EN

回答 2

Stack Overflow用户

发布于 2015-06-08 22:34:11

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

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

因此,我认为您需要创建一个任务请求队列,您的“主线程”将向其中注入任务。

池的概念是它们自己管理!您不应该与特定的工作线程通信,您应该只向它发送工作请求,然后让池在它认为合适的时候产生/终止工作线程。

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

票数 0
EN

Stack Overflow用户

发布于 2015-06-19 19:03:15

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

基本上,您必须创建一个IOmniTwoWayChannel实例,并在Task.RegisterComm(<channel>)的worker的Initialize方法中注册它的端点。

然后你可以用<channel>.Send(<message>, <data>)以一种“普通”的方式发送消息,如果你用Delphi的方式修饰它,它们将被分派到其他任务的消息方法:

代码语言:javascript
复制
procedure MessageHandler(var msg: TOmniMessage); message <message>;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30470815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档