Delphi - OTL - Связь между ThreadPool и рабочим потоком

Я использую 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) Рабочий поток никогда не запускается. Как я должен заставить мою Рабочую нить работать!:)

С уважением, Климент

2 ответа

OmniThreadLibrary тест 08_RegisterComm показывает, как общаться напрямую между двумя потоками.

По сути, вы должны создать экземпляр IOmniTwoWayChannel и зарегистрируйте свою конечную точку в работнике Initialize метод с Task.RegisterComm(<channel>),

Затем вы можете отправлять сообщения "обычным" способом с <channel>.Send(<message>, <data>) и они будут отправлены методу сообщения другой задачи, если вы украсите его способом Delphi:

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

Проверьте http://otl.17slon.com/book/doku.php?id=book:howto:connectionpool

я чувствую, что OTL основан на контейнерах данных, а не потоков.

поэтому я думаю, что вам нужно создать очередь запросов задач, в которую ваш "основной поток" будет внедрять задачи.

идея бассейнов в том, что они управляют собой! Вы не должны связываться с конкретным рабочим потоком, вы должны просто отправить рабочие запросы в него, а затем разрешить пулу порождать / уничтожать рабочие потоки так, как он считает нужным.

если вам нужна обратная связь от каждого конкретного потока, я бы предпочел включить TForm.Handle или, возможно, указатель TOmniMonitor в запись запроса задачи, и заставить рабочий поток перезванивать и связываться с формой, а не с потока с

Другие вопросы по тегам