Why is OmniThreadLibrary's ForEach blocking main thread?

倖福魔咒の 提交于 2019-11-30 19:13:17

问题


Using the OmniThreadLibrary and Delphi XE4, I am hoping to run multiple threads that process data in the background, adding speed increases to my already existing code.

When calling the procedure below, the Application GUI stops processing any input until all of the threads have completed. My understanding is that using .NoWait should allow the procedure to exit even when the threads are running.

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;

Is my understanding of the ForEach loop incorrect, suggesting I should use an alternate method to achieve background processing? Any suggestions on the correct use of the OmniThreadLibrary is appreciated.


回答1:


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.



来源:https://stackoverflow.com/questions/16880457/why-is-omnithreadlibrarys-foreach-blocking-main-thread

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