Recherche…


Syntaxe

  1. Try-except: try [instructions] sauf [[[sur E: ExceptionType]]] [else instruction] | [déclarations] se terminent;

    Try-finally: try [statements] finally [instructions] end;

Simple try..finally exemple pour éviter les fuites de mémoire

Utilisez try - finally pour éviter les fuites de ressources (telles que la mémoire) en cas d'exception lors de l'exécution.

La procédure ci-dessous enregistre une chaîne dans un fichier et empêche la TStringList de TStringList .

procedure SaveStringToFile(const aFilename: TFilename; const aString: string);
var
  SL: TStringList;
begin
  SL := TStringList.Create; // call outside the try 
  try
    SL.Text := aString;
    SL.SaveToFile(aFilename);
  finally
    SL.Free // will be called no matter what happens above
  end;
end;

Qu'une exception se produise lors de la sauvegarde du fichier, SL sera libéré. Toute exception ira à l'appelant.

Retour d'exception-sécurité d'un nouvel objet

Lorsqu'une fonction retourne un objet (par opposition à l' utilisation d' un objet transmis par l'appelant), faites attention qu'une exception ne provoque pas de fuite de l'objet.

function MakeStrings: TStrings;
begin
  // Create a new object before entering the try-block.
  Result := TStringList.Create;
  try
    // Execute code that uses the new object and prepares it for the caller.
    Result.Add('One');
    MightThrow;
  except
    // If execution reaches this point, then an exception has occurred. We cannot
    // know how to handle all possible exceptions, so we merely clean up the resources
    // allocated by this function and then re-raise the exception so the caller can
    // choose what to do with it.
    Result.Free;
    raise;
  end;
  // If execution reaches this point, then no exception has occurred, so the
  // function will return Result normally.
end;

Les programmeurs naïfs peuvent tenter d'attraper tous les types d'exception et renvoyer nil partir d'une telle fonction, mais ce n'est là qu'un cas particulier de la pratique générale découragée d'attraper tous les types d'exception sans les manipuler.

Essayez-enfin imbriqué dans try-except

Un bloc try - finally peut être imbriqué dans un bloc try - except .

try
  AcquireResources;
  try
    UseResource;
  finally
    ReleaseResource;
  end;
except
  on E: EResourceUsageError do begin
    HandleResourceErrors;
  end;
end;

Si une exception se produit dans UseResource , l'exécution passera à ReleaseResource . Si l'exception est une EResourceUsageError , l'exécution passe alors au gestionnaire d'exceptions et appelle HandleResourceErrors . Les exceptions de tout autre type ignoreront le gestionnaire d'exceptions ci-dessus et remonteront jusqu'au prochain try - except bloquer la pile d'appels.

Les exceptions à AcquireResource ou ReleaseResource entraînera l' exécution d'aller au gestionnaire d'exception, sauter le finally bloc, soit parce que le correspondant try bloc n'a pas encore été entré ou parce que le finally bloc a déjà été saisi.

Essayez, sauf imbriqué dans try-finally

Un bloc try - except peut être imbriqué dans un bloc try - finally .

AcquireResource;
try
  UseResource1;
  try
    UseResource2;
  except
    on E: EResourceUsageError do begin
      HandleResourceErrors;
    end;
  end;
  UseResource3;
finally
  ReleaseResource;
end;

Si une EResourceUsageError se produit dans UseResource2 , l'exécution passe alors au gestionnaire d'exceptions et appelle HandleResourceError . L'exception sera considérée comme gérée, donc l'exécution continuera à UseResource3 , puis ReleaseResource .

Si une exception d'un autre type se produit dans UseResource2 , alors le gestionnaire d'exception UseResource2 ici ne s'appliquera pas, l'exécution passera par-dessus l'appel UseResource3 et ira directement au bloc finally , où ReleaseResource sera appelé. Après cela, l'exécution passera au gestionnaire d'exceptions suivant lors de la création de l'exception.

Si une exception se produit dans un autre appel dans l'exemple ci-dessus, HandleResourceErrors ne sera pas appelé. En effet, aucun des autres appels ne se produit dans le bloc try correspondant à ce gestionnaire d'exceptions.

Essayez-enfin avec 2 objets ou plus

Object1 := nil;
Object2 := nil;
try
  Object1 := TMyObject.Create;
  Object2 := TMyObject.Create;
finally
  Object1.Free;
  Object2.Free;
end;

Si vous n'initialisez pas les objets avec nil dehors du bloc try-finally , si l'un d'eux ne peut pas être créé, un AV se produira sur le bloc finally, car l'objet ne sera pas nul (car il n'a pas été initialisé) et provoquera une exception.

La méthode Free vérifie si l'objet est nul, l'initialisation des deux objets avec nil évite les erreurs lors de leur libération s'ils n'ont pas été créés.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow