![]() |
Thread, Synchronize, MessageDlg & Interaktion
Hi,
ich hantiere momentan mit Threads herum und bin dabei auf ein Problem gestoßen, welches ich nicht beheben kann. Aufgabe Ich lader per Thread Informationen von einer Website und möchte, dass bei einer Fehlermeldung (Ausgabe der Website) der Benutzer per MessageDlg interagieren kann. Hierbei wählt er ob er sich erneut anmelden möchte. Ablauf
Delphi-Quellcode:
Fragen
procedure UpdateError();
var Response: Integer; begin Response := MessageDlg('Erneut anmelden?', mtWarning, [mbYes,mbNo], 0); if Response = mrYes then begin Main.StartThread('login'); end else begin Main.Pager.ActivePage := 3; end; end; function getSourcecode(): Boolean begin //Lade Ausgabe von Website //... //Prüfe ob die Ausgabe erfolgreich war Result := checkSourcecode(Sourcecode); if not(Result) begin Self.Terminate; Synchronize(UpdateError); end; end; 1) Wenn ich das Terminate in die Procedure UpdateError reinpacke, worauf bezieht sich dann das Self? Immernoch auf den Thread oder auf den Thread des Hauptformulars? Weil durch Synchronize wird ja die Funktion im Hauptthread ausgeführt, oder? 2) Ich habe festgestellt, dass der SubThread wartet, bis die Procedure UpdateError vollständig ausgeführt wurde. D.h. bis mein MessageDlg bestätigt wurde. Kann man das umgehen? Also der Thread soll dann einfach "auslaufen", sich beenden. Er hat seine Arbeit getan, er soll halt nur noch den MessageDlg anzeigen und gut ist. Momentan ist es so, dass sich das Programm vollständig aufhängt sobald ich auf Ja klicke. Ich kann 20x auf Nein klicken und dann auf Ja und es friert vollständig ein. Wenn ich direkt nach Response := MessageDlg(...); ein exit; einbaue, so funktioniert es jedoch. D.h. es muss irgendetwas mit dem Beenden & Starten der Threads zu tun haben. Die Funktion StartThread(String) prüft übrigens im Vorfeld, ob der Thread aktiv ist und beendet ihn. Hoffe ich konnte mein Problem klar vorbringen und hoffe es gibt auch eine Lösung für mein Problem :-) Freue mich schon auf eure Antworten. Vielen Dank. lg Timelesk |
AW: Thread, Synchronize, MessageDlg & Interaktion
Zitat:
Zitat:
Zitat:
Klassischer Deadlock ;) |
AW: Thread, Synchronize, MessageDlg & Interaktion
Hi,
vielen Dank für deine Antwort. Wie meinst du das mit Message an das Hauptformular senden? Ich seh da momentan nur die Möglichkeit nen Timer zu aktivieren, der halt nach 500ms ausgeführt wird und hoffe dass der Thread dann beendet ist. (ist aber definitiv keine Lösung) gruß Timelesk |
AW: Thread, Synchronize, MessageDlg & Interaktion
Naja, so wie man halt Messages sendet :stupid:
1. Du brauchst im Thread das Handle des Formulars. z.B. indem du ein public-Feld machst, und das Formular tut dann sein Handle da rein. 2. Nachricht definieren:
Delphi-Quellcode:
3. Wenn der Thread fertig ist:
const WM_ThreadFinished = WM_USER + 1234;
Delphi-Quellcode:
Im Hauptthread kannst du dann eine Methode implementieren, die genau auf diese Nachricht reagiert (message-Direktive) und da dann die Dialogbox darstellen und den Thread neu starten (vorher warten bis der alte abgearbeitet ist)
Result := checkSourcecode(Sourcecode);
if not(Result) begin Self.Terminate; PostMessage(FormHandle, WM_ThreadFinished, Integer(Result), 0); end; Alternativ kannst du auch einen neuen Thread kreieren ( halt MyThread = TMyThread.Create() ) und immer Freeonterminate auf true setzen. Dann startest du nicht einen Thread immer neu, sondern kreiert immer neue Threads, die sich nicht ins Gehege kommen. Dann kannst du dir den Message-Kram sparen - das ist definitiv die einfachere Lösung weil man sich um die Freigabe des Threads nicht mehr kümmern muss ;) |
AW: Thread, Synchronize, MessageDlg & Interaktion
Hi,
vielen Dank für deine Hilfe. Nun funktioniert alles so, wie ich es möchte. Die Message-Direktiven sind wirklich sehr nützlich. Das Formular hatte ich bereits an den Thread weitergegeben und somit besaß ich auch das Handle. Ganz verstanden hab ich das jetzt aber noch nicht. Ich habe bei PostMessage 4 Parameter: Form-Handle, Message-Code, Param1, Param2 Wobei Param nachrichtenspezifische Werte sind. Können die jeden Variablen-Typ annehmen? (Integer hast du ja oben geschrieben, was ist mit String, etc.?) Des Weiteren heißen meine Procedures folgendermaßen:
Delphi-Quellcode:
Warum muss der erste Parameter TMessage sein? Sind die 2 nachrichtenspezifischen Parameter in TMessage enthalten?
procedure WMLogin(var msg: TMessage); message WM_Login;
gruß Timelesk |
AW: Thread, Synchronize, MessageDlg & Interaktion
Zitat:
Zitat:
Zitat:
|
AW: Thread, Synchronize, MessageDlg & Interaktion
Hi,
vielen Dank für deine Hilfe. Hab ein wenig mit dem Record rumgespielt und funktioniert wunderbar. Vielen Dank noch einmal :-) gruß Timelesk |
AW: Thread, Synchronize, MessageDlg & Interaktion
Zitat:
|
AW: Thread, Synchronize, MessageDlg & Interaktion
Zitat:
Ein Ereignis würde normalerweise einen Ereigniscode blockierend ausführen. Ein Mittelweg wäre eine threadsichere Queue, in die man dann aus dem Ereigniscode eine Nachricht stellen kann. Das Ereignis wäre dann sofort abgearbeitet, der Thread läuft wie gewollt sofort weiter. Im Hauptthread kann die Queue dann z.B. durch einen Timer regelmäßig ausgelesen werden. |
AW: Thread, Synchronize, MessageDlg & Interaktion
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:06 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