Mahlzeit!
Ich habe hier eine Klassenstruktur, die, auf das Wesentliche resduziert, wie folgt ausschaut:
Delphi-Quellcode:
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;
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.
In TMy
SubThread 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ö!
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)