![]() |
Threads mit Callback im Mainthread
Hallo Zusammen,
folgende Problematik. Ich Arbeite mit einem Hintergrundthread der Daten zur Anzeige aufbereitet (TBitmaps). Sobald ein Bild erzeugt wurde wird es mit: TThread.Queue(nil, procedure begin FOnLoadPicture(FBitmap); end ); An den Mainthread "übertragen". Danach läuft der Thread weiter und bereitet das nächste Bild vor. Am Ende gibt sich der Thread dann selbst frei. Da das FOnLoadPicture() ja in dem Thread definiert ist könnte es doch sein, dass der Thread freigegeben wird bevor diese Funktion im Mainthread gelaufen ist oder? Dann wäre das FOnLoadPicture ja nicht mehr gültig. Oder verstehe ich das falsch? Über jeden Tipp mit dem ich ein bisschen Licht ins Dunkle bekomme wäre ich sehr dankbar. Liebe Grüße |
AW: Threads mit Callback im Mainthread
Den Delphi-Knopf hast du nicht gesehn? (den mit dem griechischen Helm)
Zitat:
Die Variable wird ja zwischen Thread und Queue-Proc automatisch geshared, aber das Objekt darin .... tja, da es kein Interface ist, sondern ein Objekt, und wenn dann dieses Objekt weg ist oder zwischendrin verändert wurde, oder gar "grade eben" im Thread zeitgleich wieder verändert wird, dann bist du selbst daran Schuld, wenn es knallt. Ordentlich absichern (CriticalSections oder so) oder richtig synchronisieren, so dass wirklich immer nur Einer gleichzeitig. Bei einem Synchronize würde der Thread warten, bis das Andere fertig ist. |
AW: Threads mit Callback im Mainthread
Ja das macht Sinn. Ich meinte nur das FOnLoadPicture. Das ist wie folgt definiert:
TOnLoadPicture = procedure(Const aBitmap:TBitmap) of object; FOnLoadPicture:TOnLoadPicture; property OnLoadPicture:TOnLoadPicture read FOnLoadPicture write FOnLoadPicture; Wenn der Thread freigegeben wird ist ja auch das FOnLoadPicture weg oder nicht? P.S.: Hatte den Helm tatsächlich nicht gesehen :D |
AW: Threads mit Callback im Mainthread
Alle Variablen/Parameter, welche von außen in die anonyme Methode (die Prozedur im Queue) rein gereicht werden,
werden als Kopie in einem "internen" Interface abgelegt, welches die übergeordnete Prozedur und die Anonyme sich teilen. Ups ja, das betrifft doch nicht FOnLoadPicture. :oops: In Wirklichkeit sieht es bei dir ja so aus.
Delphi-Quellcode:
TThread.Queue(nil,
procedure begin Self.FOnLoadPicture({Self.?}FBitmap); end ); Beispiel:
Delphi-Quellcode:
und intern sieht es dann eigentlich so aus, nach dem Kompilieren (so in etwa)
procedure TMiau.ABC(Param: Irgendwas);
var Blubb: Sonstwas; begin Blubb := ...; TThread.Queue(nil, procedure begin Machwas(Param, Blubb); {Self.}FOnLoadPicture({Self.}FBitmap); end );
Delphi-Quellcode:
Also ja, wenn Self (dein Thread) weg ist, dann wäre auch FOnLoadPicture weg,
procedure TMiau.ABC(Param: Irgendwas);
type IGeheimesVariablenInterface = interface Self: TMiau; Blubb: Sonstwas; Param: Irgendwas; end; TGeheimesVariablenInterface = class(TInterfacedObject, IGeheimesVariablenInterface) .. end; var XXX: IGeheimesVariablenInterface; begin XXX := TGeheimesVariablenInterface.Create; XXX.Param := Param; XXX.Blubb := ...; TThread.Queue(nil, procedure var YYY: IGeheimesVariablenInterface := XXX; begin Machwas(XXX.Param, XXX.Blubb); XXX.Self.FOnLoadPicture(XXX.Self.FBitmap); end ); es sei denn du legst dir innerhalb deiner übergeordneten Prozedur eine lokale Variable an, wo dieser Wert gespeichert und der dann an die Queue übergeben wird. (entsprechend Blubb) Wäre "Self" wiederum ein Interface, anstatt eines Objektes, dann sähe die Sache wieder etwas anders aus, da die zusätzliche Referenz dessen Lebensdauer ja verlängern würde, bis die anonyme Methode beendet ist. |
AW: Threads mit Callback im Mainthread
PS: Darum auch aufpassen, dass man sowas nicht in einer Schleife nutzt, sondern dann nochmal in einer Methode mit Parametern kapselt,
da das geheime Variableninterface dann ja von außen immer wieder überschrieben wird, also auch innerhalb der mehreren Anonymen sich der Inahlt ändern würde.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var X: Integer; begin for var i := 1 to 3 do begin X := Random(100); TThread.ForceQueue(nil, procedure begin ShowMessage(X.ToString); // alle zeigen den gleichen "letzten" Zufallswert end); end; end; |
AW: Threads mit Callback im Mainthread
Also meinst du ich soll am Besten alles was ich noch brauche in eine Temp-Variable speichern?
Irgendwie habe ich trotzdem ein ungutes Gefühl, dass irgendwas schief gehen könnte ... |
AW: Threads mit Callback im Mainthread
Nimm einfach Synchronize nicht Queue!
Mavarik :coder: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:33 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