![]() |
Zugriff auf TProgressbar.Position aus TThread.Queue
Benutze D11.2 und Versuche mittels TThread.Queue ein Progressbar aus einem Task heraus zu aktualisieren. Das crasht jedoch. Ein Label das in der selben Methode den selben Wert ausgibt crasht nicht.
Woran kann es liegen? |
AW: Zugriff auf TProgressbar.Position aus TThread.Queue
Zitat:
|
AW: Zugriff auf TProgressbar.Position aus TThread.Queue
|
AW: Zugriff auf TProgressbar.Position aus TThread.Queue
Und wenn du es mit TTask.Run machst? (Vergiss nicht das Synchronize, ansonsten ruft der das aus einem anderen Thread auf!)
|
AW: Zugriff auf TProgressbar.Position aus TThread.Queue
![]() Darum ist auch das Wie wichtig. z.B. Variable benutzen, die es "dann" nicht mehr gibt = ungünstig oder Variable benutzen, die "dann" im Thread überschrieben sein/werden kann = ungünstig, weil nicht mehr synchron oder ... |
AW: Zugriff auf TProgressbar.Position aus TThread.Queue
Sitze gerade vor einem anderen PC aber im Prinzip so:
Delphi-Quellcode:
So ungefähr. Ja, was wirklich im Task läuft ist noch etwas demo mäßig und wird später ersetzt.
type
TOnProgress = procedure(Sender: TObject; Progress: UInt32) of Object; TMyWorker = class(TObject) private FOnProgress : TOnProgress; procedure ReportProgress(Progress: UInt32); public procedure DoIt; property OnProgress : TOnProgress read FOnProgress write FOnProgress; end; procedure TMyWorker.Dot; begin TTask.Run( for var i := 0 to 100 do begin ReportProgress(i); sleep(50); end); end; procedure TMyWorker.ReportProgress(Progress: UInt32); begin TThread.Queue(procedure if Assigned(FOnProgress) then FOnProgress(self, Progress); end); end; [..] TMainForm = class(TForm) pb_Progrsss : TProgressBar; Label1: TLabel; private FWorker : TMyWorker ; public procedure OnProgress(Sender: TObject; Progress: UInt32); procedure DoSomething; end; [..] procedure TMainForm.OnProgress(Sender: TObject; Progress: UInt32); begin Label1.Caption := Progress.ToString; pb_Progress.Position := Progress; end; procedure TMainForm.DoSomething; begin FWorker.DoIt; end; |
AW: Zugriff auf TProgressbar.Position aus TThread.Queue
Der Progress-Parameter ist sicher, weil da macht der Generic die anonyme Methode sich eine Copie von.
Bei OnProgress hat nicht, denn dort hat der nur eine Kopie des Self, welches nur so lange gültig ist, wie die TMyWorker-Instanz läuft. Bei Synchronize kein Problem ... aber bem Queue muß man aufpassen. Allerdings könnte man sich auch eine lokale Variable für OnProgress in ReportProgress anlegen ... dann ist TMyWorker egal und man muß nur noch auf das achten, wohin das Event geht, also TMainForm (hier gäbe es in Queue(procedure Möglichkeiten das gegenzuprüfen, z.B. über Application.MainForm, bzw. über Screen.Forms, ob der Form-Zeiger noch valide ist). Ansonsten: TStaticText, bzw. TPanel anstatt TLabel und dann kann es als "richtiges" WinControl auch auf Messages reagieren, also SendMessage(WM_SETTEXT), bzw SetWindowText und die ProgessBar auf PostMessage mit PBM_SETPOS. SendMessage, weil wegen dem "PChar", der ja bei Ausführung noch gültig sein muß. In das WndProc des Label kann man auch eine Message mit "Interger"-Parameter gängen, welcher Diesen nach String übersetzt und an Caption übergibt ... das ginge dann wieder als PostMessage. PostMessage direkt an das Fenster/Control ... verschwindet das Fenster/Control vor Abarbeitung der Message in der MessageQueue (PostMessage), dann räumt Windows diese Message orgendlich auf ... kein eventuelle Ausführen nach Freigabe des Controls. Bei der TThread.Queue wäre es also nett, könnte man sie auch (optional) an ein TWinControl/HWND oder zumindestens an ein TControl hängen. (dann würde Windows/Delphi die Prüfung ob noch da übernehmen) |
AW: Zugriff auf TProgressbar.Position aus TThread.Queue
Bitte nicht an dem Sender Parameter aufhängen.
Der wird ja im GUI gar nicht benutzt. Die Anzeige des Wertes per Label funktioniert, bei der Zuweisung des Position des Progress Bar knallt es. C0000005 oder so... Meiner Meinung nach dürfte es doch da aber gar kein Problem geben, da die Queue es ja dann abarbeitet, wenn es für den GUI passt. => wo ist mein Problem hier? Ja, mit Messages könnte man das sicher lösen, dann wäre aber die Geschäftslogik an Windows gebunden... Grüße TurboMagic |
AW: Zugriff auf TProgressbar.Position aus TThread.Queue
Wenn du dann wieder vor dem passenden PC sitzt, mach doch bitte ein minimales Beispiel, damit wir das hier auch nachvollziehen können.
|
AW: Zugriff auf TProgressbar.Position aus TThread.Queue
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:18 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