首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么OmniThreadLibrary的ForEach阻塞主线程?

为什么OmniThreadLibrary的ForEach阻塞主线程?
EN

Stack Overflow用户
提问于 2013-06-02 14:46:55
回答 1查看 1.3K关注 0票数 2

使用OmniThreadLibrary和Delphi XE4,我希望在后台运行多个线程来处理数据,为我已经存在的代码增加速度。

当调用下面的过程时,应用程序GUI停止处理任何输入,直到所有线程都完成为止。我的理解是,使用.NoWait应该允许过程退出,即使线程正在运行。

代码语言:javascript
复制
procedure Test(input: TStringList; output: TList<TMaintFore>);
var
  outQueue: IOmniBlockingCollection;
  transaction: TOmniValue;
begin
  outQueue := TOmniBlockingCollection.Create;
  Parallel.ForEach(0, input.Count - 1)
    .NoWait
    .Into(outQueue)
    .Execute(
      procedure(const value: integer; var result: TOmniValue)
      begin
        result := TMaintFore.Create(input[value]);
      end
    );
end;

我对ForEach循环的理解是错误的,这意味着我应该使用另一种方法来实现后台处理?任何有关正确使用OmniThreadLibrary的建议都将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-02 15:38:22

您必须将从Parallel.ForEach返回的接口存储在一个全局(表单等)变量中,并仅在ForEach完成执行时销毁它。

在您的示例中,ForEach的结果存储在一个临时变量中,该变量在测试过程退出时被销毁。ForEach析构函数等待所有任务完成,这会阻塞您的程序。

在任务完成时销毁foreach接口的最安全(但无可否认的不明显)方法是使用OnStop方法,并从该方法向主线程发出命令。

代码语言:javascript
复制
var
  loop: IOmniParallelLoop<integer>;

loop := Parallel.ForEach(1, N).NoWait;
loop.OnStop(
  procedure (const task: IOmniTask)
  begin
    task.Invoke(
      procedure
      begin
        // do anything
        loop := nil;
      end);
  end);
loop.Execute(
  procedure (const value: integer)
  begin
    ...
  end);

the wiki中记录了这一点。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16880457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档