![]() |
AW: MultiThreading
Zitat:
Zitat:
|
AW: MultiThreading
Ähm ja, ist kein richtiger Freeze, wenn die Liste nicht aufgebaut wäre, würde die Verarbeitung sie aufbauen müssen. Es ist also nur eine Teilaufgabe und die muss immer vollständig abgeschlossen sein, bevor etwas es weiter geht.
@Uwe Hast du etwas Code, damit man den Aufwand ggf. abschätzen kann? |
AW: MultiThreading
Zitat:
Delphi-Quellcode:
myform.OnClick(Sender:tObject);
Bgein MyGUIListview.enabled := false; MYGUiAnyIndicator.visibe := true; // Anzeige Animation im Hauptthread das die Liste aktualisiert wird. TThread.CreateAnonymousThread( procedure Begin var data:Tarray<TMyItemdataRec> := LoadDataForaShitLoadOfTime; // das dauert. //laden fertig ? ok call back in den GUI Thread mit ForceQueue, // es kann sein dass der Thread schneller fertig ist als die GUI // braucht um die liste disabled neu zu zeichnen und ich mag // es in der richtigen Reienfolge wegen BeginUpdate udn EndUpdate // daher ForceQueue; TThreading.ForceQueue(nil, Procedure begin MyGUIListview.BeginUpdate; MyGUIListview.clear; For Var i:integer := 0 to high(data) do AddTMyListview(data[i]); MyGUIListview.Enabled := true; MyGUIListview.EndUpdate; MYGUiAnyIndicator.visible := false; end // procedure )//TThreading.ForceQueue(nil, end // procedure ).Start; // TThread.CreateAnonymousThread( end;//myform.OnClick(Sender:tObject); |
AW: MultiThreading
Und wenn man Feedback und Fehlerbehandlung braucht so
Delphi-Quellcode:
Type
TResultData = Record Success:boolean; Error:String; Data:Tarray<TMyItemdataRec>; end; myform.OnClick(Sender:tObject); Bgein MyGUIListview.enabled := false; MYGUiAnyIndicator.visibe := true; // Anzeige Animation im Hauptthread das die Liste aktualisiert wird. TThread.CreateAnonymousThread( procedure// ThreadProcedure Begin var aResult:TResultData := LoadDataForaShitLoadOfTime; // das dauert. If aResult.Success then Begin //laden fertig ? ok call back in den GUI Thread mit ForceQueue, // es kann sein dass der Thread schneller fertig ist als die GUI // braucht um die liste disabled neu zu zeichnen und ich mag // es in der richtigen Reienfolge wegen BeginUpdate udn EndUpdate // daher ForceQueue; TThreading.ForceQueue(nil, Procedure //ForceQueue begin If aResult.Success then Begin MyGUIListview.BeginUpdate; MyGUIListview.clear; For Var i:integer := 0 to length(aResult.data)-1 do AddTMyListview(aResult.data[i]); MyGUIListview.Enabled := true; MyGUIListview.EndUpdate; MYGUiAnyIndicator.visible := false; end //If aResult.Success then else Begin Log(' LoadDataForaShitLoadOfTime:'+aResul.error); MyGUIListview.Enabled := true; MYGUiAnyIndicator.visible := false; ShowMessage(aResul.error); end //else If aResult.Success then end // procedure //ForceQueue )//TThreading.ForceQueue(nil, end // procedure// ThreadProcedure ).Start; // TThread.CreateAnonymousThread( end;//myform.OnClick(Sender:tObject); |
AW: MultiThreading
Zitat:
Delphi-Quellcode:
Bei der Verwendung prüft man dann den Status des Future auf Completed und reagiert entsprechend.
unit uMyList;
interface function MyList: TStringList; function MyListFuture: IFuture<TStringList>; implementation uses System.Threading; var InternalFuture: IFuture<TStringList>; InternalList: TStringList; function MyList: TStringList; begin Result := InternalFuture.Value; end; function MyListFuture: IFuture<TStringList>; begin Result := InternalFuture; end; initialization InternalList := TStringList.Create; InternalFuture := TTask.Future<TStringList>( function: TStringList begin Result := InternalList; for var I := 1 to 10000000 do Result.Add(I.ToString); end); finalization InternalList.Free; InternalList := nil; end; Alternativ würde es hier auch genügen lediglich den TTaskStatus öffentlich zu machen. Dann muss aber System.Threading eh schon in der uses-Anweisung stehen. Das Future bietet zudem noch die Möglichkeit des Cancel. Angenommen die Bearbeitung erfolgt auf einen Button-Click. Dann würde ich den Button mit einer TAction mit einem entsprechenden Execute-Event verbinden (sollte übrigens eh schon so sein). Im OnUpdate könnte dann sowas stehen:
Delphi-Quellcode:
Damit lässt sich der Button nur klicken, wenn die Liste fertig ist,
begin
(Sender as TAction).Enabled := (MyListFuture.Status = TTaskStatus.Completed); end; Dort ließe sich auch eine Behandlung für Canceled bzw. Exception unterbringen. |
AW: MultiThreading
Danke, das scheint überschaubar. Mal sehen wie weit ich das umsetze.
|
AW: MultiThreading
Zitat:
Also nicht von innen durch abfragen von "Terminated"? |
AW: MultiThreading
Zitat:
|
AW: MultiThreading
Zitat:
Mein Problem ist dass Futures bei mir immer die Oberfläche analten... Ich habe immer nur den GUI Thread und evtl. einen Thread der etwas im Hintergrund tut. Gibt es irgend einen Grund warum ich das lieber in Itask.run statt in einem anonymen Thread machen sollte? |
AW: MultiThreading
Zitat:
Es kommt halt immer drauf an was man alles braucht. ITask bzw. IFuture bieten z.B. auch gleich zwei Wait Overloads, mit denen man auch leicht ein non-freezing Poll implementieren kann. Vieles von dem müsste man bei einem simplen anonymen Thread noch selbst beisteuern. Nicht das das nicht auch möglich wäre. In einem mittlerweile schon über drei Jahre alten Blog Post beschreibe ich den durchaus etwas längeren Weg von Synchron zu Asynchron: ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:57 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-2025 by Thomas Breitkreuz