Ecriture de blocs finally

De RAD Studio
Aller à : navigation, rechercher

Remonter à Définition des blocs protégés


Un gestionnaire d’exception est le code qui gère une exception spécifique ou toutes les exceptions se produisant dans un bloc de code protégé. Toutefois, il arrive parfois que vous n'ayez pas besoin de gérer l'exception, mais que vous souhaitiez exécuter du code après le bloc protégé, même si une exception se produit. Généralement, ce type de code gère ce qui a trait au nettoyage, comme la libération des ressources allouées avant le bloc protégé.

L'utilisation de blocs finally garantit la libération des ressources allouées par votre application, même si une exception se produit. Par conséquent, quand votre application alloue de la mémoire, vous pouvez vous assurer qu’elle la libère bien. De même, si elle ouvre un fichier, vous pouvez vous assurer que le fichier est bien fermé ultérieurement. Dans une situation normale, vous pouvez garantir qu’une application libère les ressources allouées en spécifiant simplement le code d’allocation et de libération des ressources. Quand des exceptions ont lieu, vous devez vous assurer que l’application exécute quand même le code de libération des ressources.

Certaines ressources courantes doivent toujours être libérées :

  • Fichiers
  • Mémoire
  • Ressources Windows ou ressources des bibliothèques de widgets (objets Qt)
  • Objets (instances de classes dans votre application)

Le gestionnaire d'événement suivant montre comment une exception peut empêcher une application de libérer la mémoire qu'elle alloue :

 
  procedure TForm1.Button1Click(Sender: TObject);
  var
  APointer: Pointer;
  AnInteger, ADividend: Integer;
  begin
    ADividend := 0;
    GetMem(APointer, 1024);{ allocate 1K of memory }
    AnInteger := 10 div ADividend;{ this generates an exception }
    FreeMem(APointer, 1024);{ this never gets called because of the exception}
  end;

Toutes les erreurs ne sont pas aussi évidentes, mais cet exemple illustre un principe important : En cas d'exception, l’exécution sort du bloc et l’instruction qui libère la mémoire n’est jamais appelée.

Pour que la mémoire soit libérée, vous pouvez utiliser un bloc try avec un bloc finally.

Ecriture d'un bloc 'finally'

Les blocs finally sont introduits par le mot clé finally. Ils font partie d'une instruction try..finally, qui présente la forme suivante :

try
{ statements that may raise an exception}
finally
{ statements that are called even if there is an exception in the try block}
end;

Dans une instruction try..finally, l’application exécute toujours les instructions placées dans la partie finally, même quand des exceptions se produisent dans le bloc try. Si du code du bloc try (ou une routine appelée par du code du bloc try) déclenche une exception, l’exécution s’interrompt là. Quand un gestionnaire d’exception est trouvé, l’exécution se poursuit dans la partie finally, qui est appelée le “code de nettoyage”. Une fois la partie finally exécutée, le gestionnaire d’exception est appelé. Quand il n’y a pas d’exception, le code de nettoyage est exécuté dans l’ordre normal après toutes les instructions du bloc try.

Le gestionnaire d’événement défini par le code suivant utilise un bloc finally de telle sorte que, lorsqu'il alloue de la mémoire et génère une erreur, il libère quand même la mémoire allouée :

procedure TForm1.Button1Click(Sender: TObject);
var
APointer: Pointer;
AnInteger, ADividend: Integer;
begin
  ADividend := 0;
  GetMem(APointer, 1024);{ allocate 1K of memory }
  try
    AnInteger := 10 div ADividend;{ this generates an exception }
  finally
    FreeMem(APointer, 1024);{ execution resumes here, despite the exception }
  end;
end;

Les instructions placées dans le bloc finally ne dépendent pas de l’apparition d’une exception. Si les instructions de la partie try ne déclenchent pas d’exception, l’exécution se poursuit quand même par le bloc finally.

Voir aussi