【问题标题】:How to pass params to Parallel.Async() in OmniThreadLibrary?如何将参数传递给 OmniThreadLibrary 中的 Parallel.Async()?
【发布时间】:2013-05-11 15:16:48
【问题描述】:

如何将一些参数从主线程传递给工作线程(即下面的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 中),有一个名为 Paramcommented out 属性,如下所示:

//    property Param: TOmniValueContainer read GetParam;

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

【问题讨论】:

  • 这确实是一个奇怪的问题,以“如何”开头,正确回答“否”......:P
  • @MasonWheeler,也许吧,我希望这个问题能得到很好的描述,你知道,这里不会说英语:P

标签: delphi omnithreadlibrary


【解决方案1】:

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

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

如果您不熟悉匿名方法的变量捕获,请参阅 documentation

【讨论】:

  • 在目前离线的OTL论坛上提出了同样的问题。这是它的缓存副本的链接:webcache.googleusercontent.com/… 如您所见,Primoz 建议使用变量捕获。
  • 感谢您的链接,大卫!在发帖之前,我确实尝试过进入 OTL 论坛。我认为这会奏效。我想知道,当Foo() 内部时,MyParam 物理上是编译器制作的副本,而逻辑上它与最初声明的相同?
  • 我想如果我们在Foo()里面写信给MyParam也可以吗?
  • 如果你愿意,你可以写信给它。你可以从中获得各种乐趣。再次致电Async 并让两个匿名方法都写入MyParam 并在您的匿名方法之间进行工程通信!
  • @EdwinYip:这不是“逻辑上相同的副本”。它是同一个变量,但它存在于匿名方法的支持函子对象中,而不是在它声明的过程中。我写了一个关于几年前发生的细节的解释:tech.turbu-rpg.com/13/whats-in-a-name-less-method
【解决方案2】:

我的简短回答

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

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

您的 sn-p 中的 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。 IE。 msg := task.Param['Message'];

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

【讨论】:

  • 感谢您的帮助。实际上我也一直在使用较低级别的方法,我喜欢它给了我细粒度的控制,另一方面,Parallel.Async 在某些情况下非常方便,因为你将所有逻辑放在一起 in一个地方,而不是把逻辑分散在各处。
  • 没问题。 Parallel.Async 看起来确实很方便。真的,整个框架看起来非常整洁。昨天我花了很多时间阅读有关 OTL 的内容,并为尝试将其纳入我的下一个项目而感到兴奋和兴奋。之后,我意识到这样的目标与我开始熟悉 Firemonkey 的目标相冲突(这样我可以在需要时制作多平台应用程序)。让我想哭。
  • 我最近的发现是CreateTask()、OnTerminated() 等都接受匿名方法!所以CreateTask() 几乎和Parallel.Async() 一样方便,而且非常灵活!
猜你喜欢
  • 2020-09-01
  • 2015-11-24
  • 2018-09-30
  • 2020-10-09
  • 2012-12-21
  • 2012-01-07
  • 2014-05-03
  • 2015-06-26
  • 2012-01-18
相关资源
最近更新 更多