Why is OmniThreadLibrary's ForEach blocking main thread?

丶灬走出姿态 提交于 2019-12-01 00:19:51

You have to store the interface returned from the Parallel.ForEach in a global (form etc) variable and destroy it only when the ForEach finishes execution.

In your example, the result of ForEach is stored in a temporary variable which is destroyed when the Test procedure exits. The ForEach destructor waits for all tasks to complete and that blocks your program.

The safest (but admittedly non-obvious) way to destroy the foreach interface on task completion is to use the OnStop method and from it queue a command to the main thread.

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);

This is documented in the wiki.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!