3

如何将一些参数从主线程传递到工作线程(即以下procedure)?

Parallel.Async(
  procedure (const task: IOmniTask)
  begin
    //How does one pass in 'myParam' from the main thread, so that the statement bellow will work?
    s := task.Param['myParam'].AsString;
  end
);

如果检查IOmniTaskConfig(在 OtlParallel.pas 中)的定义,则有一个commented out名为 的属性Param,如下所示:

//    property Param: TOmniValueContainer read GetParam;

所以我想我的问题的答案是否定的,但我希望不是!

4

2 回答 2

4

您应该为此使用变量捕获。

var
  MyParam: Integer;
....
MyParam := 42;
Parallel.Async(
  procedure(const task: IOmniTask)
  begin
    Foo(MyParam);
  end
);

如果您不熟悉匿名方法的变量捕获,可以在文档中进行详细讨论。

于 2013-05-16T16:10:08.930 回答
4

我的简短回答

Parallel.Async 旨在与匿名方法一起使用,这样做可以让您从调用方法中捕获变量(正如 David Heffernan 已经证明的那样)。

我的长答案(因为您特别询问了 Param 集合)

您的task.Param代码段中的 没有引用IOmniTaskConfig界面中的属性。它指的是IOmniTaskControl接口中的 Param 属性。这是一个合法的财产,但据我所知(考虑到我今天才开始研究 OTL 并且还没有使用它,这不是很多),您必须编写自己的ASync程序才能写入以任何有意义的方式获得财产。

开箱即用的 Param 属性旨在与 OTL 的低级功能一起使用。例如:

FHelloTask :=
   CreateTask(RunHello, 'Hello')
   .SetParameter('Delay', 1000)
   .SetParameter('Message', 'Hello')
   .OnMessage(HandleTaskMessage)
   .OnTerminated(HandleTaskTerminated)
   .Run;

该代码将创建一个线程并运行“RunHello”过程,该过程可以访问DelayMessage通过它的任务参数。IEmsg := task.Param['Message'];

ASync 基本上是一个包装器,CreateTask它自动将其添加到线程池中,提供一些 IOmniTaskConfig 支持,并具有一些错误处理的东西。总而言之,它是一个类方法,大约有 20 行代码。制作您自己的实现 SetParameter 过程的 ASync 版本可能不是一件非常困难的事情。不过,我个人现在太累了,无法干预它,而且我宁愿在开始破解它之前完成对 OTL 的学习。此外,仅使用匿名方法来捕获变量也很容易。

于 2013-05-17T06:48:19.487 回答