Exécution asynchrone (FireDAC)

De RAD Studio
Aller à : navigation, rechercher

Remonter à Utilisation des commandes (FireDAC)

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 :

AsyncExecuteDialogPicture.png

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.