Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi - OTL - Communicating between ThreadPool and Worker thread

I'm using XE8 and I'm trying to built an example of my real world application.

I need to communicate between the main "service thread" and the OTL thread pool. The examples are all set with forms and Monitors. I don't need those, but I can't figure out a way to write a clean code. So far this is what I did:

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;

Implemented as:

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;

In the main thread, to create the pool, I'm calling:

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);

I don't know how to call correctly my worker thread. In my real application, several thread will be triggered and I need to be sure I using correctly the threadpool.

1) By calling CreateTask as I am, how am I making a correct use of threadpool? It's seems odd to me to call CreateTask for every Process I need.

2) The worker thread is never triggered. How should I make my Worker thread work! :)

Regards, Clément

like image 341
Clément Avatar asked Jan 23 '26 21:01

Clément


1 Answers

OmniThreadLibrary test 08_RegisterComm shows how to communicate directly between two threads.

Basically, you have to create an instance of IOmniTwoWayChannel and register its endpoint in the worker's Initialize method with Task.RegisterComm(<channel>).

You can then send messages in a 'normal' way with <channel>.Send(<message>, <data>) and they will be dispatched to other task's message method if you decorate it in a Delphi way:

procedure MessageHandler(var msg: TOmniMessage); message <message>;
like image 178
gabr Avatar answered Jan 26 '26 13:01

gabr