![]() |
TParallel for: wie Schleife abbrechen?
Leider sind die Informationen zur TParallel-Library noch sehr spärlich.
Wie kann man eine TParallel.for schleife eigentlich vorzeitig abbrechen? Also abbrechen, bevor alle Iterationen durchlaufen sind? Ein "break" scheint es nicht zu geben. |
AW: TParallel for: wie Schleife abbrechen?
Du musst dir ein zentrales Break selber bauen ...
Delphi-Quellcode:
procedure Foo;
var LBreak: Boolean; LValue: Integer; begin LBreak := False; LValue := 0; TParallel.&For( 1, 1000, procedure( L: Integer ) begin if not LBreak then begin Inc( LValue ); LBreak := L = 100; end; end ); Writeln( LValue ); end; |
AW: TParallel for: wie Schleife abbrechen?
OK, das geht, aber offensichtlich wird die For Schleife dann trotzdem die vorgesehene Anzahl durchlaufen, nur, dass eben nichts abgearbeitet wird.
Gibt es da wirklich nichts anderes? Mal Frage am Rande: Warum verwendest Du immer "Tparallel.&For", statt "TParallel.For"? In der Hilfe steht es auch mit "&", warum eigentlich? |
AW: TParallel for: wie Schleife abbrechen?
Ja, da gibt es doch ein Break (mir war doch auch so :oops:)
Delphi-Quellcode:
Da wird auf jeden Fall früher abgebrochen, allerdings laufen ein paar Tasks noch durch die Schleife. Sieht man schön, wenn man das ausführt
procedure Foo;
var LValue: Integer; begin LValue := 0; TParallel.&For( 1, 1000, procedure( L: Integer; S: TParallel.TLoopState ) begin if not S.ShouldExit then begin Inc( LValue ); if L = 500 then S.Break; end; end ); Writeln( LValue ); end;
Delphi-Quellcode:
Bei mir kommt dann regelmäßig 529 heraus.
procedure Foo;
var LValue: Integer; begin LValue := 0; TParallel.&For( 1, 1000, procedure( L: Integer; S: TParallel.TLoopState ) begin // if not S.ShouldExit // then // begin Inc( LValue ); if L = 500 then S.Break; // end; end ); Writeln( LValue ); end; |
AW: TParallel for: wie Schleife abbrechen?
Zitat:
Delphi-Quellcode:
ein reserviertes Wort ist. Und um das so zu deklarieren muss man ein
for
Delphi-Quellcode:
davor setzen.
&
Delphi-Quellcode:
;)
TFoo = class
procedure &For; procedure &Type; procedure &Begin; procedure &End; procedure &Class; procedure &procedure; end; |
AW: TParallel for: wie Schleife abbrechen?
Super, so was hatte ich gesucht, aber leider nicht gefunden.
|
AW: TParallel for: wie Schleife abbrechen?
Zitat:
![]()
Delphi-Quellcode:
Und wenn ich nicht weiß, was
class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorEvent): TLoopResult; overload; static; inline;
class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorEvent; APool: TThreadPool): TLoopResult; overload; static; inline; class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorStateEvent): TLoopResult; overload; static; inline; class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorStateEvent; APool: TThreadPool): TLoopResult; overload; static; inline; class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorEvent): TLoopResult; overload; static; inline; class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorEvent; APool: TThreadPool): TLoopResult; overload; static; inline; class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorStateEvent): TLoopResult; overload; static; inline; class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Integer; AIteratorEvent: TIteratorStateEvent; APool: TThreadPool): TLoopResult; overload; static; inline; class function &For(ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer>): TLoopResult; overload; static; inline; class function &For(ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer>; APool: TThreadPool): TLoopResult; overload; static; inline; { da } class function &For(ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer, TLoopState>): TLoopResult; overload; static; inline; { da } class function &For(ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer, TLoopState>; APool: TThreadPool): TLoopResult; overload; static; inline; class function &For(AStride, ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer>): TLoopResult; overload; static; inline; class function &For(AStride, ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer>; APool: TThreadPool): TLoopResult; overload; static; inline; { da } class function &For(AStride, ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer, TLoopState>): TLoopResult; overload; static; inline; { da } class function &For(AStride, ALowInclusive, AHighInclusive: Integer; const AIteratorEvent: TProc<Integer, TLoopState>; APool: TThreadPool): TLoopResult; overload; static; inline; class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorEvent64): TLoopResult; overload; static; inline; class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorEvent64; APool: TThreadPool): TLoopResult; overload; static; inline; class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorStateEvent64): TLoopResult; overload; static; inline; class function &For(Sender: TObject; ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorStateEvent64; APool: TThreadPool): TLoopResult; overload; static; inline; class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorEvent64): TLoopResult; overload; static; inline; class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorEvent64; APool: TThreadPool): TLoopResult; overload; static; inline; class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorStateEvent64): TLoopResult; overload; static; inline; class function &For(Sender: TObject; AStride, ALowInclusive, AHighInclusive: Int64; AIteratorEvent: TIteratorStateEvent64; APool: TThreadPool): TLoopResult; overload; static; inline; class function &For(ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64>): TLoopResult; overload; static; inline; class function &For(ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64>; APool: TThreadPool): TLoopResult; overload; static; inline; { da } class function &For(ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64, TLoopState>): TLoopResult; overload; static; inline; { da } class function &For(ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64, TLoopState>; APool: TThreadPool): TLoopResult; overload; static; inline; class function &For(AStride, ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64>): TLoopResult; overload; static; inline; class function &For(AStride, ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64>; APool: TThreadPool): TLoopResult; overload; static; inline; { da } class function &For(AStride, ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64, TLoopState>): TLoopResult; overload; static; inline; { da } class function &For(AStride, ALowInclusive, AHighInclusive: Int64; const AIteratorEvent: TProc<Int64, TLoopState>; APool: TThreadPool): TLoopResult; overload; static; inline;
Delphi-Quellcode:
oder
TLoopState
Delphi-Quellcode:
ist, und die Doku nicht weiterweiß, dann einfach ein STRG-Klick auf das Unbekannte und direkt im Quelltest nachschauen ;)
TLoopResult
BTW:
Delphi-Quellcode:
/
TIteratorStateEvent
Delphi-Quellcode:
haben auch noch den
TIteratorStateEvent64
Delphi-Quellcode:
:)
TLoopState
|
AW: TParallel for: wie Schleife abbrechen?
Ich muss gestehen, das hatte ich gesehen, aber das Gewünschte nicht gefunden (ist ja auch ein wenig unübersichtlich...).
Was soll eigentlich s.shouldexit bewirken? Wenn man das aufruft, hat das anscheinend keine Auswirkungen? In System.Threading gibt es das da:
Delphi-Quellcode:
EDIT: Oh, jetzt gesehen, dass Shoudexit einen Wert zurückgibt, nicht setzt. Wäre aber gut, wenn man die Rückgabe von SharedFlags.ShouldExit mit True hinkriegen könnte, dann wir die While-Schleife unterbrochen
class function TParallel.ForWorker...
while (I < ToExclusive) and ((SharedFlags.LoopStateFlags = []) or not SharedFlags.ShouldExit) do |
AW: TParallel for: wie Schleife abbrechen?
Öhm, das ist doch offensichtlich und darum habe ich den Code doch auch in 2 Variationen eingestellt. Einmal mit Abfrage
Delphi-Quellcode:
und einmal ohne. Bei beiden wird die Verarbeitung der Tasks vorzeitig abgebrochen, allerdings sind einige Tasks schon über dem PointOfNoReturn und werden trotzdem noch durch die Worker-Threads verarbeitet.
s.ShouldExit
Und genau für diese durchgerutschten Tasks frage ich den LoopState
Delphi-Quellcode:
ab. Und wenn man vorher ein
TLoopState
Delphi-Quellcode:
aufgerufen hat, dann liefert
TLoopState.Break
Delphi-Quellcode:
ganz lapidar ein
TLoopState.ShouldExit
Delphi-Quellcode:
.
True
Genau das wollen wir doch haben ... oder nicht? |
AW: TParallel for: wie Schleife abbrechen?
Man hätte es aber auch einfacher implementieren können, indem man z.B. auch auf
![]() Aber wenn man in dem For-Event etwas längeres macht, oder eine Schleife, dann sollte man da natürlich auch den State prüfen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:17 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz