Asynchrone Ausführung (FireDAC)
Nach oben zu Arbeiten mit Anweisungen (FireDAC)
Inhaltsverzeichnis
Allgemeine Informationen
Programmierer können mithilfe der Eigenschaft ResourceOptions.CmdExecMode unter vier Ausführungsmodi wählen:
Modus | Beschreibung |
---|---|
amBlocking | Der aufrufende Thread und die Benutzeroberfläche sind so lange blockiert, bis eine Aktion beendet ist. |
amNonBlocking | Der aufrufende Thread ist so lange blockiert, bis eine Aktion beendet ist. Die Benutzeroberfläche ist nicht blockiert. |
amCancelDialog | Der aufrufende Thread und die Benutzeroberfläche sind so lange blockiert, bis eine Aktion beendet ist. FireDAC zeigt ein Dialogfeld an, in dem die Aktion abgebrochen werden kann. |
amAsync | Der aufrufende Thread und die Benutzeroberfläche sind nicht blockiert. Die aufgerufene Methode kehrt sofort zurück. |
Eine Anwendung überprüft TFDCommand.State oder TFDAdaptedDataSet.Command.State hinsichtlich des Ausführungsstatus:
Status | Beschreibung |
---|---|
csInactive | Es wird keine Anweisung vorbereitet. |
csPrepared | Eine Anweisung wird vorbereitet. Auf eine Ergebnismenge kann nicht zugegriffen werden. |
csExecuting | Eine Anweisung wird gerade ausgeführt. |
csOpen | Die Ausführung einer Anweisung ist beendet. Auf eine Ergebnismenge kann zugegriffen werden, aber sie ist noch nicht vollständig abgerufen. |
csFetching | Das Abrufen einer Ergebnismenge wird gerade ausgeführt. |
csAborting | Der Abbruch einer Anweisungsausführung wird gerade ausgeführt. |
Zum Beispiel:
FDQuery1.ResourceOptions.CmdExecMode := amAsync;
FDQuery1.Open;
while FDQuery1.Command.State = csExecuting do begin
// do something while query is executing
end;
Im Modus amCancelDialog wird ein Benutzer über Operationen mit langen Ausführungszeiten informiert, und er hat die Möglichkeit, die Operation mit der TFDGUIxAsyncExecuteDialog-Komponente abzubrechen:
Ziehen Sie die Dialogfeld-Komponente auf ein Formular. Eine weitere Konfiguration ist nicht erforderlich. In der Eigenschaftsbeschreibung von ResourceOptions.CmdExecMode finden Sie weitere Einzelheiten über Modi und Benachrichtigungsereignisse.
Asynchrones Öffnen und Abrufen
Wenn eine Anwendung eine Abfrage asynchron (amAsync) öffnen muss und die Abfrage über TDataSource an die Benutzeroberfläche gebunden ist, muss die Verbindung von TDataSource zur Abfrage vor dem Öffnen der Abfrage aufgehoben und nach dem Öffnen der Abfrage wiederhergestellt werden. Zum Beispiel:
procedure TForm1.FDQuery1BeforeOpen(DataSet: TDataSet);
begin
DataSource1.DataSet := nil;
end;
procedure TForm1.FDQuery1AfterOpen(DataSet: TDataSet);
begin
DataSource1.DataSet := FDQuery1;
FDQuery1.ResourceOptions.CmdExecMode := amBlocking;
end;
FDQuery1.BeforeOpen := FDQuery1BeforeOpen;
FDQuery1.AfterOpen := FDQuery1AfterOpen;
FDQuery1.ResourceOptions.CmdExecMode := amAsync;
FDQuery1.Open;
Dies ist nicht erforderlich, wenn amCancelDialog verwendet wird. Zudem kann das Abrufen über die Benutzeroberfläche nicht im amAsync-Modus durchgeführt werden. Um eine Abfrage zu öffnen und große Ergebnismengen asynchron abzurufen, setzen Sie FetchOptions.Mode auf fmAll. Dann werden beide Operationen als eine einzige Hintergrundaufgabe durchgeführt.
- Hinweis: Dieses Vorgehen ist nur zulässig, wenn Sie eine bidirektionale Datenmenge verwenden.
Verwenden Sie eine separate Transaktion für die Abfrage, um diese Firebird-Abfrage asynchron auszuführen.
Abbrechen von Operationen mit langen Ausführungszeiten
Ein Programmierer kann die Zeitüberschreitung für Datenzugriffsoperationen mit der Eigenschaft ResourceOptions.CmdExecTimeout festlegen. Wenn für eine Operationsausführung mehr als die angegebene Zeit erforderlich ist, wird die Ausführung abgebrochen und eine Exception ausgelöst. Verwenden Sie den folgenden Code, um eine Zeitüberschreitung einer Anweisung abzufangen:
try
// set timeout to 5 seconds
FDQuery1.ResourceOptions.CmdExecTimeout := 5000;
FDQuery1.ExecSQL;
except
on E: EFDDBEngineException do
if E.Kind = ekCmdAborted then
; // command is aborted
end;
Alternativ kann die Anwendung die Operationsausführung durch Aufrufen der Datenmenge oder der Anweisungsmethode AbortJob aus einem anderen Thread abbrechen oder die Verbindungsmethode AbortJob aufrufen, um alle Operationen für diese Verbindung abzubrechen.
- Hinweis: Nicht alle FireDAC-Treiber und DBMSs unterstützen das Abbrechen der Ausführung. Außerdem kann der Abbruch nicht sofort durchgeführt werden, wenn das DBMS wichtige Operationen ausführt. Die folgende Tabelle enthält die unterstützten Kombinationen:
DBMS | Bemerkungen |
---|---|
Advantage | |
IBM DB2 | |
Firebird | Version 2.5 oder höher |
Informix | |
InterBase | Version 7.0 oder höher |
MySQL | Version 5.0 oder höher |
Oracle | |
PostgreSQL | |
SQL Anywhere | |
SQL Server | |
SQLite | |
Teradata Database |
Mehrere asynchrone Abfragen
Die parallele Ausführung mehrerer asynchroner Abfragen wird von FireDAC wegen des allgemeinen Multithread-Grundsatzes nicht unterstützt. Ziehen Sie die folgenden Optionen zur Umgehung dieses Problems in Betracht:
- Gruppieren Sie mehrere Abfragen in einer gespeicherten Prozedur, und rufen Sie die Prozedur asynchron auf.
- Verwenden Sie eine eigene Verbindung für jede asynchrone Abfrage, die parallel ausgeführt wird.
- Rufen Sie die nächste asynchrone Abfrage auf, nachdem die vorherige beendet wurde. Verwenden Sie dazu die Ereignisbehandlungsroutinen AfterOpen und AfterExecute.
- Schließlich kann die Anwendung eigene Threads erstellen und die DB-Aufgaben in diesen Threads ausführen.