multithreading - 退出 Parallel.For 循环的最快方法?

标签 multithreading delphi delphi-10.1-berlin

当用户单击“取消”按钮或用户关闭/销毁表单时,我需要以最快的方式退出 TParallel.For 循环。我已尝试使用 TParallel.TLoopState.StopTParallel.TLoopState.Break:

var
  BreakCondition: Boolean;

procedure TForm2.DoStartLoop;
begin
  BreakCondition := False;
  System.Threading.TParallel.For(1, 50,
    procedure(idx: Integer; LS: TParallel.TLoopState)
    begin
      if BreakCondition then
      begin
        //LS.&BREAK;
        LS.STOP;
        //EXIT;
      end
      else
        DoProcessValue(idx);
    end);
end;

不幸的是,TParallel.TLoopState.StopTParallel.TLoopState.Break 的 Embarcadero 文档仅指出:

Embarcadero Technologies does not currently have any additional information.

我还有这样的印象:循环不会很快中断。有更好的办法吗?

最佳答案

From the TParallel.For documentation :

If control of the iteration itself is needed from the iterator event, the iterator event handler should be one using the TParallel.TLoopState parameter. When present, the event handler will be given an instance of TParallel.TLoopState from which state information from Faulted,Stopped, or ShouldExit can be monitored, or the iteration loop itself can be controlled with the Break or Stop methods.

跟踪 LoopState 的方法是使用具有以下签名的方法:

TIteratorStateEvent = 
  procedure (Sender: TObject; AIndex: Integer; const LoopState: TLoopState) of object;

或者使用其匿名版本:

class function &For(AStride, ALowInclusive, AHighInclusive: Integer; 
const AIteratorEvent: TProc<Integer, TLoopState>; APool: TThreadPool): TLoopResult;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

如果文档失败,最简单的方法是搜索类的源代码,或者让代码完成来完成工作。

TLoopState = class
    private [...]
    public
      procedure Break;
      procedure Stop;
      function ShouldExit: Boolean;  <<-- this looks useful

      property Faulted: Boolean read GetFaulted;
      property Stopped: Boolean read GetStopped;  <<-- or this
      property LowestBreakIteration: Variant read GetLowestBreakIteration;
    end;

示例:

procedure TForm1.btnParallelForClick(Sender: TObject);
var
  Tot: Integer;
  SW: TStopwatch;
begin
     try
     // counts the prime numbers below a given value
       Tot :=0;
       SW :=TStopWatch.Create;
       SW.Start;
       //Use a method that supports LoopState
       TParallel.For(2,1,Max,procedure(I:Int64; State: TLoopState)
       begin
         //check loopstate every now and again.
         if State.ShouldExit then exit;  
         if IsPrime(I) then TInterlocked.Increment(Tot);
       end);
     SW.Stop;
      Memo1.Lines.Add(Format('Parallel For loop. Time (in milliseconds): %d - Primes found: %d', [SW.ElapsedMilliseconds,Tot]));
     except on E:EAggregateException do
      ShowMessage(E.ToString);
     end;
end;

关于multithreading - 退出 Parallel.For 循环的最快方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43790289/

相关文章:

java - 从线程访问主 Activity 中的变量

c++ - pthread 之间共享和不共享的属性是什么

java - 为什么运行 Camel 示例需要在主线程上 hibernate

delphi - 将 delphi win32 应用程序转换为库和 FreeLibrary 卡住

android - 使用 TStyleBook 时的旧/暗对话框

delphi - Rtti 调用类方法显示无效类型转换

c# - 如果在线程尚未完成时覆盖 Thread 对象,会发生什么情况?

delphi - 如何从VCL重新编译特定单元?

delphi - 如何使用 TIdMessage 和 Delphi XE 发送包含希腊字符的电子邮件 *更新*

delphi - 如何在文字上使用 TExtendedHelper?