Hallo
DB-Profis,
folgende Situation:
-------------------
Ich greife mit eigenen Komponenten über eigene
SQL-Funktionen auf eine
FB-Datenbank zu.
Die
SQL-Funktionen fordern aus einem Pool eine (oder mehrere) freie IBSql an, deklarieren eine passende
SQL-Klausel, führen sie aus und geben sie zur Freigabe wieder an den Pool zurück.
Bevor der Pool eine freie IBSql herausgibt (und ggf. vorab bei Bedarf eine eine neue erzeugt) wird eine Standard-IBDatabase und IBTransaction zugewiesen.
Das funktioniert auch wunderbar
Nun gibt es aber eine etwas zeitintensive Funktion (TMyComponent.Compare), die 1-2 Sekunden dauern kann und im Ergebnis einiger
SQL-Abfragen ein paar Schalter aktiviert bzw. deaktiviert.
Dies wollte ich daher in einem Thread ausführen, damit der Anwender in der Zeit z.B. schon mal weiter tippen kann. Dies führt jedoch zu Problemen, insbesondere zu der Fehlermeldung "invalid request
handle".
Werden die
SQL-Funktionen im Rahmen eines solchen Threads ausgeführt, muss ich dann wohl statt der Standard-IBDatabase eine Thread-eigene IBDatabase verwenden (soweit ich gelesen habe)...
Überlegung:
-----------
Ich muss also in der Pool-Komponente beim Bereitstellen einer freien IBSql unterscheiden, ob gerade "die Anwendung" oder "ein Thread" für die Aktion zuständig ist.
Das sollte dann in etwa so aussehen:
Delphi-Quellcode:
function TMyPool.IBSql: TIBSql;
var
IBSql: TIBSql;
MyThread: TThread;
MyIBDatabase: TIBDataBase;
begin
IBSql := FreieOderNeueIBSql;
MyThread := CurrentThread; // Instanz eines selbst gestarteten Thread ermitteln
if not Assigned(MyThread) then // Hauptprozess läuft
begin
IBSql.Database := StandardIBDatabase;
IBSql.Transaction := StandardIBTransaction;
end
else
begin // eigener Thread läuft
MyIBDatabase := TIBDataBase.Create(MyThread);
MyIBDatabase.StartTransaction;
IBSql.Database := MyIBDatabase;
IBSql.Transaction := MyIBDatabase.Transaction;
end;
Result := IBSql;
end;
Jetzt meine Fragen:
-------------------
1) Sind so überhaupt Thread-Zugriffe auf eine
FB-EMBEDDED-
DB möglich oder gibt es vielleicht eine einfachere Lösung?
2) Muss der jeweilige Thread Owner der "neuen IBDatabase" sein (sonst kann ich evtl. auf die Instanzsuche des Thread verzichten und lediglich auswerten, OB ein Thread läuft)?
3) Gibt es eine bessere Möglichkeit, die Thread-Instanz zu ermitteln, als diese in einer eigenen Liste zu sammeln und zu suchen (ich starte die Threads immer selbst)?
4) GetCurrentThread liefert mir immer ein
Handle <> 0, auch wenn kein "externer" Thread gestartet wurde (sicher ist das das
Handle des Anwendungsprozesses). Wie kann ich erkennen, ob es sich bei dem
Handle um eine "extra gestarteten" Thread außerhalb des Hauptprozesses handelt (egal ob von mir gestartet oder z.B. von einer Fremdkomponente) -> CurrentHandleIsNotMainProcess
5) Was bedeutet "Pseudo-
Handle" in dem Zusammenhang? Kann ich mit GetCurrentThread eigentlich unterschiedliche Instanzen des gleichen Thread(typs) finden?
Danke
Stahli