Ich habe gerade festgestellt, dass meine Ausnahmen dem Benutzer in meinen Threads nicht angezeigt werden!
Zuerst habe ich das in meinem Thread benutzt, um die Ausnahme auszulösen, was nicht funktioniert:
%Vor%Die IDE zeigt mir die Ausnahmen, aber meine App nicht!
Ich habe nach einer Lösung gesucht, das habe ich gefunden:
Delphi Thread-Ausnahmemechanismus
Und beides funktionierte nicht für mich.
Hier ist meine Thread-Einheit:
%Vor%Wenn Sie weitere Informationen benötigen, lassen Sie es mich wissen.
Nochmal: Die IDE fängt alle Ausnahmen ab, aber mein Programm zeigt sie nicht an.
EDIT: Es war Cosmins Lösung, die am Ende funktionierte - und der Grund, warum es nicht zuerst war, war, dass ich die ErrMsg-Variable nicht hinzugefügt habe, sondern einfach alles, was die Variable enthalten würde, in die Synchronize-Funktion legte würde nicht funktionieren, aber ich habe keine Ahnung warum. Ich habe es realisiert, als ich keine anderen Ideen hatte, und ich habe nur mit den Lösungen herumgespielt.
Wie immer ist der Witz auf mich. = P
Hier ist mein sehr, sehr kurzer "Take" zu dem Thema. Es funktioniert nur mit Delphi 2010+ (da diese Version anonyme Methoden eingeführt hat). Im Gegensatz zu den ausgefeilteren Methoden zeigt mine nur die Fehlermeldung, nicht mehr und nicht weniger.
%Vor%Etwas sehr Wichtiges, das Sie über die Multi-Thaded-Entwicklung verstehen müssen:
Jeder Thread hat seinen eigenen Aufruf-Stack, fast , als wären es separate Programme. Dies beinhaltet den Haupt-Thread Ihres Programms.
Threads können nur auf bestimmte Arten miteinander interagieren:
NB : Beachten Sie, dass Threads streng genommen andere Threads nicht direkt aufrufen können. Wenn zum Beispiel Thread A versucht, Thread B direkt aufzurufen, wäre das ein Schritt auf dem Call-Stack von Thread A!
Dies bringt uns zum Thema der Frage: "Ausnahmen werden in meinen Threads nicht ausgelöst"
Der Grund dafür ist, dass alles eine Ausnahme ist:
So wird TThread nicht automatisch Ausnahmen für Ihre Hauptanwendung melden.
Sie müssen die explizite Entscheidung treffen, wie Sie Fehler in Threads behandeln und entsprechend implementieren möchten.
TIP: Make sure the exception doesn't escape the thread. The OS won't like you if it does.
EDIT: Codebeispiel für die angegebene Anforderung.
Wenn Sie lediglich den Benutzer benachrichtigen möchten, Cosmind Prunds Antwort sollte für Delphi 2010 perfekt funktionieren. Ältere Versionen von Delphi brauchen etwas mehr Arbeit. Das Folgende ist konzeptionell ähnlich wie Jeffs eigene Antwort , aber ohne die Fehler :
%Vor%Einige wichtige Korrekturen zu Jeffs eigener Antwort, einschließlich der Implementierung in seiner Frage:
Der Aufruf von Terminate
ist nur relevant, wenn Ihr Thread in einer while not Terminated do
... -Schleife implementiert ist. Sehen Sie sich an, was die Methode Terminate
tatsächlich macht.
Der Aufruf von Exit
ist eine unnötige Verschwendung, aber Sie haben das wahrscheinlich wegen Ihres nächsten Fehlers getan.
In Ihrer Frage wickeln Sie jeden Schritt in seinem eigenen try...except
ab, um die Ausnahme zu behandeln. Das ist ein absolutes no-no ! Indem Sie dies tun, geben Sie vor, dass, obwohl eine Ausnahme aufgetreten ist, alles in Ordnung ist. Ihr Thread versucht den nächsten Schritt, aber es ist tatsächlich garantiert fehlgeschlagen! Dies ist nicht die Art, Ausnahmen zu behandeln!
Threads verbreiten Ausnahmen nicht automatisch in andere Threads. Du musst also selbst damit umgehen.
Rafael hat einen Ansatz skizziert, aber es gibt Alternativen. Die Lösung, auf die Rafael hinweist, behandelt die Ausnahme synchron, indem sie in den Hauptthread eingeordnet wird.
In einer meiner eigenen Threading-Anwendungen, einem Thread-Pool, fangen und übernehmen die Threads den Besitz der Ausnahmen. Dies ermöglicht es dem steuernden Thread, sie so zu behandeln, wie es Ihnen gefällt.
Der Code sieht so aus.
%Vor%Wenn der steuernde Thread die Ausnahme auswählt, kann er dies folgendermaßen tun:
%Vor%Manchmal haben Sie möglicherweise Code, der Synchronize nicht aufrufen kann, z. einige DLLs und dieser Ansatz ist nützlich.
Beachten Sie, dass wenn Sie die Ausnahme, die erfasst wurde, nicht auslösen, dann muss es zerstört werden, andernfalls haben Sie einen Speicherverlust.
Nun,
Es wird schwer ohne Ihren Quellcode, aber ich habe das getestet:
So behandeln Sie Ausnahmen in TThread-Objekten
Und es funktioniert gut. Vielleicht sollten Sie es sich ansehen.
BEARBEITEN:
Sie folgen nicht den Anweisungen, auf die Sie uns hinweisen. Überprüfen Sie meinen Link und Sie werden sehen, wie das geht.
EDIT 2:
Probieren Sie das aus und sagen Sie mir, ob es funktioniert hat:
%Vor%EDIT 3:
Sie haben gesagt, dass Sie EIdHTTPProtocolException nicht abfangen können. Aber es funktioniert für mich. Probieren Sie dieses Beispiel aus und sehen Sie es sich selbst an:
%Vor%Ich habe zuvor SendMessge für die Inter-Thread-Kommunikation mit TWMCopyData verwendet, daher sollte das Folgende funktionieren:
%Vor%Ich habe es nur benutzt, um einfache Datentypen oder Strings zu senden, aber ich bin mir sicher, dass es angepasst werden könnte, um mehr Informationen nach Bedarf zu senden.
Sie müssen Self.Handle
zum Konstruktor hinzufügen, indem Sie den Thread erstellt und die Nachricht in der Form bearbeitet haben, in der sie erstellt wurde
Seltsam, dass alle diese Frage beantwortet haben, aber das offensichtliche Problem nicht erkannt haben: Da in einem Hintergrund-Thread generierte Ausnahmen asynchron sind und jederzeit auftreten können, würde das Anzeigen von Ausnahmen aus einem Hintergrundthread einen Dialog öffnen Box zu zufälligen Zeiten an den Benutzer, möglicherweise eine Ausnahme, die nichts mit dem zu tun hat, was der Benutzer im Moment tut. Ich bezweifle, dass dies möglicherweise die Benutzererfahrung verbessern könnte.
Tags und Links multithreading delphi exception raise tthread