Einzelnen Beitrag anzeigen

Medium

Registriert seit: 23. Jan 2008
3.679 Beiträge
 
Delphi 2007 Enterprise
 
#1

TUniConnection.Connected nicht verlässlich?

  Alt 5. Aug 2011, 12:21
Datenbank: MySQL • Version: 4.1.9 • Zugriff über: UniDAC
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 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ö!
"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)
  Mit Zitat antworten Zitat