![]() |
Datenbank: MySQL • Version: 4.1.9 • Zugriff über: UniDAC
TUniConnection.Connected nicht verlässlich?
Mahlzeit!
Ich habe hier eine Klassenstruktur, die, auf das Wesentliche resduziert, wie folgt ausschaut:
Delphi-Quellcode:
Das Problem ist nun, dass wenn ich meinen MySQL Server einfach mal beende, so merkt die Connection in TMyThread richtigerweise, dass sie nicht mehr ".Connected" ist, und die eigentliche Routine wird durch Reconnectversuche ersetzt, bis die Welt wieder i.O. ist.
type
TMySubThread = class(TThread) private FConnection: TUniConnection; protected Execute; override; public constructor Create(aConnection: TUniConnection); property Connection: TUniConnection read FConnection; end; TMyThread = class(TThread) private FConnection: TUniConnection; FSubThread: TMySubThread; hasSubThread: Boolean; protected Execute; override; public constructor Create(aConnection: TUniConnection); end; implementation { TMyThread } constructor TMyThread.Create(aConnection: TUniConnection); begin FConnection := TUniConnection.Create(nil); FConncetion.AssignConnect(aConnection); // Noch eine TUniQuery erzeugen, an FConnection binden, und ein paar Dinge // aus meiner DB ermitteln. // Anhand dieser Infos wird entschieden, ob ein SubThread erzeugt wird, oder nicht. // Sollte KEIN SubThread erzeugt werden, wird die hier erstellte Connection in der // Execute-Methode von TMyThread weiter verwendet, wird ein SubThread erzeugt, kann // sie weg. Also: if SomeInfosFromDBMandateIt then begin FSubThread := TMySubThread.Create(aConnection); FConnection.Free; hasSubThread := true; end; end; procedure TMyThread.Execute; begin repeat if ((not hasSubThread) and (not FConnection.Connected)) or ((hasSubThread) and (not FSubThread.Connection.Connected)) then begin if not hasSubThread then FConnection.Connect; end else begin if not hasSubThread then begin // Hier die eigentliche Arbeit, u.a. mit FConnection end else begin // Hier andere Arbeit, die keine DB-Zugriffe an dieser Stelle tätigt, // sondern nur auf Flags aus dem SubThread reagiert. end; end; Sleep(1); until Terminated; end; { TMySubThread } constructor TMySubThread.Create(aConnection: TUniConnection); begin FConnection := TUniConnection.Create(nil); FConncetion.AssignConnect(aConnection); end; procedure TMySubThread.Execute; begin repeat if not FConnection.Connected then FConnection.Connect else begin // Hier die andere eigentliche Arbeit... end; Sleep(1); until Terminated; end; In TMySubThread allerdings klappt das nicht! Dort ist FConnection.Connected immer true, auch wenn der Server ganz sicher weg ist. Das merke ich u.a. daran, dass ich 2 dieser TMyThreads laufen habe, einen mit Sub- und einen ohne. Der ohne meldet ganz richtig (per Windows-Message an ein Formular, welches es darstellt; wollte den QT nicht zu lang machen) einen Verbindungsverlust. Der SubThread dagegen läuft munter weiter, und versucht in seiner Execute-Methode weiterhin fröhlich Queries abzusetzen. (Der if-Zweig in TMySubThread.Execute wird nie erreicht, und Connected als "true" via Debugger bestätigt. Also auch keine Exception bei diesem Zugriff, der Thread hüpft in den else-Zweig weiter.) Warum liefert Connected mir in dem einen Fall das richtige Ergebnis, im anderen aber nicht? So gesehen sind TMyThread und TMySubThread ja gleichwertig, egal wer da jetzt in meinem Programm eine Referenz auf wen hält - aus Systemsicht sollte das völlig egal sein, nur verhalten sie sich nicht gleich. Hat da grad jemand eine gute Idee für mich übrig? Dankö! |
AW: TUniConnection.Connected nicht verlässlich?
Neue Informationslage:
TUniConnection.AssignConnect() war keine gute Idee, da es tatsächlich die die ganze Connection umbiegt, und nicht nur die Logindaten und Serversettings setzt. Also das raus geworfen, um wirklich getrennte Connection zu haben, in beiden Threadklassen. Das Problem besteht allerdings weiterhin :( Interessant ist jedoch: Im TMySubThread.Execute() wird die meiste Zeit keine Query abgesetzt, da dies nur bei einer Änderung gemacht wird, die zuvor dort ermittelt wird. Bisher habe ich nur ohne Änderungen getestet. Setze ich dort wirklich eine Query ab, gibt's eine AV - was zu erwarten war. Stecke ich dies nun also in ein try..except, und schreibe im Ausnahmefall manuell "FConnection.Disconnect;", ist der Wert von FConnection.Connected in der Folge korrekt. Ich muss aber um das zu merken erst auf den Hammer laufen, was in TMyThread nicht nötig ist. Doof dabei ist: Änderungen treten teils länger nicht auf, und so lange dem so ist, merke ich den Disconnect nicht. Allerdings ließe sich eine Menge Netzwerktraffic (den ich bei bestehender Verbindung auch anderweitig erzeuge, Polling... bäh), so wie ein Haufen unnützer Log-Einträge sparen, wenn ich den Disconnect schon merken würde wenn er passiert ist. Immer und immer wieder, auch bei keinem Bedarf, eine Query nur zum Prüfen der Verbindung abwerfen fände ich aber auch nicht so genial, zumal es in TMyThread ja geht. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:58 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