2

私は 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) ワーカー スレッドがトリガーされることはありません。ワーカー スレッドを機能させるにはどうすればよいですか。:)

よろしく、クレメント

4

2 に答える 2

0

http://otl.17slon.com/book/doku.php?id=book:howto:connectionpoolを確認してください

私の感覚では、OTL はスレッドではなく、データ コンテナーに基づいていると思います。

したがって、「メインスレッド」がタスクを挿入するタスクリクエストのキューを作成する必要があると思います。

プールのアイデアは、プールが自分自身を管理するということです! 特定のワーカー スレッドと通信するべきではありません。ワーク リクエストをそこに送信するだけで、プールがワーカー スレッドをスポーン/キルできるようにする必要があります。

特定のすべてのスレッドからのフィードバックが必要な場合は、TForm.Handle または TOmniMonitor ポインターをタスク リクエスト レコードに含めて、ワーカー スレッドがコールバックしてフォームと通信するようにします。

于 2015-06-08T14:34:10.900 に答える
0

OmniThreadLibrary テスト08_RegisterCommは、2 つのスレッド間で直接通信する方法を示しています。

基本的に、 のインスタンスを作成し、IOmniTwoWayChannelそのエンドポイントをワーカーのInitializeメソッドに登録する必要がありますTask.RegisterComm(<channel>)

その後、「通常の」方法でメッセージを送信できます。Delphi の<channel>.Send(<message>, <data>)方法で装飾すると、メッセージは他のタスクのメッセージ メソッドにディスパッチされます。

procedure MessageHandler(var msg: TOmniMessage); message <message>;
于 2015-06-19T11:03:15.387 に答える