Exécution asynchrone (FireDAC)
Remonter à Utilisation des commandes (FireDAC)
Sommaire
Informations générales
Un programmeur peut choisir entre quatre modes d'opération en utilisant la propriété ResourceOptions.CmdExecMode :
Mode | Description |
---|---|
amBlocking | Le thread appelant et l'interface utilisateur graphique (GUI) sont bloqués jusqu'à la fin d'une action. |
amNonBlocking | Le thread appelant est bloqué jusqu'à la fin d'une action. La GUI n'est pas bloquée. |
amCancelDialog | Le thread appelant et l'interface utilisateur graphique (GUI) sont bloqués jusqu'à la fin d'une action. FireDAC affiche une boîte de dialogue permettant d'annuler une action. |
amAsync | Le thread appelant et la GUI ne sont pas bloqués. La méthode appelée retourne immédiatement. |
Une application contrôle TFDCommand.State ou TFDAdaptedDataSet.Command.State pour connaître le statut d'une opération :
Statut | Description |
---|---|
csInactive | Une commande n'est pas préparée. |
csPrepared | Une commande est préparée. Un ensemble de résultats n'est pas accessible. |
csExecuting | Une exécution de commande est en cours. |
csOpen | Une exécution de commande est terminée. Un ensemble de résultats est accessible et pas encore entièrement extrait. |
csFetching | Une extraction d'ensemble de résultats est en cours. |
csAborting | Une interruption d'exécution de commande est en cours. |
Par exemple :
FDQuery1.ResourceOptions.CmdExecMode := amAsync;
FDQuery1.Open;
while FDQuery1.Command.State = csExecuting do begin
// do something while query is executing
end;
Avec le mode amCancelDialog, l'utilisateur est informé des opérations dont l'exécution est longue et a la possibilité d'annuler l'opération en utilisant le composant TFDGUIxAsyncExecuteDialog :
Pour utiliser le composant dialogue, déposez-le sur une fiche. Aucune configuration supplémentaire n'est requise. Pour en savoir plus sur les modes et les événements de notification d'opération, consultez la description de la propriété ResourceOptions.CmdExecMode.
Ouverture et extraction asynchrones
Lorsqu'une application doit ouvrir une requête de manière asynchrone (amAsync) et que cette requête est liée à la GUI en utilisant TDataSource, ce dernier doit être déconnecté de la requête avant son ouverture, puis reconnecté après l'ouverture. Par exemple :
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;
Cela n'est pas nécessaire lorsque amCancelDialog est utilisé. Par ailleurs, il est impossible de procéder à l'extraction avec la GUI en mode amAsync. Pour ouvrir une requête et extraire des ensembles de résultats volumineux de manière asynchrone, définissez FetchOptions.Mode sur fmAll. Les deux opérations sont alors effectuées comme une tâche d'arrière-plan unique.
- Remarque : Ce processus est valide uniquement lorsque vous utilisez un ensemble de données bidirectionnel.
Pour exécuter de manière asynchrone la requête Firebird, utilisez une transaction séparée pour cette requête.
Annulation des opérations dont l'exécution est longue
Un programmeur peut spécifier le délai d'expiration d'une opération d'accès aux données en utilisant la propriété ResourceOptions.CmdExecTimeout. Lorsque l'exécution d'une opération requiert un délai supérieur à celui spécifié, l'exécution est annulée et une exception est déclenchée. Pour spécifier le délai d'expiration d'une commande, utilisez le code suivant :
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;
Sinon, l'application annule l'exécution de l'opération en appelant la méthode AbortJob de l'ensemble de données ou de la commande à partir d'un autre thread, ou la méthode AbortJob de la connexion pour annuler toutes les opérations sur cette connexion.
- Remarque : L'annulation de l'exécution n'est pas prise en charge par tous les pilotes FireDAC et tous les SGBD. Par ailleurs, l'annulation ne peut pas être effectuée immédiatement lorsqu'un SGBD est en train d'exécuter des opérations critiques. Le tableau suivant présente les combinaisons supportées :
SGBD | Remarques |
---|---|
Advantage | |
IBM DB2 | |
Firebird | v 2.5 ou supérieure |
Informix | |
InterBase | v 7.0 ou supérieure |
MySQL | v 5.0 ou supérieure |
Oracle | |
PostgreSQL | |
SQL Anywhere | |
SQL Server | |
SQLite | |
Base de données Teradata |
Requêtes asynchrones multiples
L'exécution parallèle de plusieurs requêtes asynchrones n'est pas supportée par FireDAC, en raison du principe général de multi-threading. Pour contourner ce problème, vous pouvez utiliser l'une des options suivantes :
- Regroupez plusieurs requêtes dans une procédure stockée et appelez la procédure de manière asynchrone.
- Utilisez une connexion dédiée pour chaque requête asynchrone s'exécutant en parallèle.
- Lancez la requête asynchrone suivante une fois la précédente terminée. Pour cela, utilisez les gestionnaires d'événement AfterOpen et AfterExecute.
- Enfin, l'application peut créer ses propres threads et exécuter les tâches de base de données dans ces threads.