cdew / omnithreadlibrary

Automatically exported from code.google.com/p/omnithreadlibrary
0 stars 0 forks source link

Parallel.ForEach appears to wait even though .NoWait is specified #41

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
When the below procedure is run, the Main GUI does not respond to any updates 
until all the threads have completed. It seems that calling .NoWait does not do 
anything.

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
    );
//    for transaction in outQueue do
//    begin
//      output.Add(transaction.AsObject as TMaintFore);
//    end;
end;

When TMaintFore.Create is called, a lot of processing occurs due to the amount 
of data that is available. "input" contains a list of approx 12 files, so for 
ForEach will initiate 12 threads for processing. Could it be that this is too 
many at one time? I am not sure if I am overloading the system or if .NoWait is 
just failing to work.

I am using Delphi XE4.

Original issue reported on code.google.com by eik...@internode.on.net on 2 Jun 2013 at 2:37

GoogleCodeExporter commented 9 years ago
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.

Original comment by gabr42 on 2 Jun 2013 at 7:38