Suche…


Syntax

  1. Try-Exception: try [Anweisungen] außer [[[[bei E: ExceptionType do-Anweisung]] [else-Anweisung] | [Anweisungen] Ende;

    Try-finally: try [Anweisungen] finally [Anweisungen] end;

Einfaches try..finally Beispiel, um Speicherlecks zu vermeiden

Verwenden Sie try - zum finally , um Ressourcenlecks (wie Speicher) zu vermeiden, falls während der Ausführung eine Ausnahme auftritt.

Die folgende Prozedur speichert eine Zeichenfolge in einer Datei und verhindert, dass die 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;

Unabhängig davon, ob beim Speichern der Datei eine Ausnahme auftritt, wird SL freigegeben. Jede Ausnahme geht an den Anrufer.

Ausnahmesichere Rückgabe eines neuen Objekts

Wenn eine Funktion ein Objekt zurückgibt (im Gegensatz zur Verwendung eines Objekts, das vom Aufrufer übergeben wurde), ist zu beachten, dass eine Ausnahme das Objekt nicht verliert.

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;

Naive Programmierer versuchen möglicherweise, alle Ausnahmetypen abzufangen und nil aus einer solchen Funktion zurückzugeben. nil ist jedoch nur ein Spezialfall der generell unmutigen Praxis, alle Ausnahmetypen zu erfassen, ohne sie zu behandeln.

Try-endlich verschachtelt in Try-Exceptions

Ein try - finally - Block kann innerhalb eines try - mit except Blocks - verschachtelt sein.

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

Wenn innerhalb von UseResource eine Ausnahme auftritt, UseResource Ausführung zu ReleaseResource . Wenn die Ausnahme ein EResourceUsageError , springt die Ausführung zum Ausnahmehandler und ruft HandleResourceErrors . Ausnahmen eines anderen Typs überspringen den Ausnahmebehandler oben und blasen bis zum nächsten try - except Blockieren des Aufrufstapels.

Ausnahmen in AcquireResource oder ReleaseResource dazu, dass die Ausführung an den Ausnahmebehandler geht und den finally Block überspringt, entweder weil der entsprechende try Block noch nicht eingegeben wurde oder weil der finally Block bereits eingegeben wurde.

Try-Ausnahme verschachtelt in Try-finally

Ein try - except Block kann innerhalb eines try - finally Blocks verschachtelt sein.

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

Wenn in UseResource2 ein EResourceUsageError auftritt, UseResource2 Ausführung zum Ausnahmehandler und ruft HandleResourceError . Die Ausnahme wird als behandelt betrachtet, sodass die Ausführung weiterhin bei UseResource3 und dann bei ReleaseResource .

Wenn in UseResource2 eine Ausnahme eines anderen Typs auftritt, wird der hier angegebene Ausnahmebehandler nicht UseResource3 Ausführung springt dann über den Aufruf von UseResource3 und geht direkt zum finally Block, in dem ReleaseResource aufgerufen wird. Danach springt die Ausführung zum nächsten anwendbaren Ausnahmebehandlungsprogramm, da die Ausnahmebedingung den Aufrufstapel aufbläst.

Wenn bei einem anderen Aufruf im obigen Beispiel eine Ausnahme auftritt, werden HandleResourceErrors nicht aufgerufen. Dies liegt daran, dass keine der anderen Aufrufe innerhalb des try Blocks erfolgt, der diesem Ausnahmehandler entspricht.

Try-finally mit 2 oder mehr Objekten

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

Wenn Sie die Objekte nicht mit " nil außerhalb des try-finally Blocks initialisieren, wird beim try-finally Block ein AV ausgelöst, da das Objekt nicht null ist (da es nicht initialisiert wurde) und wird eine Ausnahme verursachen.

Die Free Methode prüft, ob das Objekt null ist. Wenn Sie beide Objekte mit nil initialisieren, werden Fehler vermieden, wenn Sie sie freigeben, wenn sie nicht erstellt wurden.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow