Embarcadero Delphi
Verwendung von try außer und zum Schluss
Suche…
Syntax
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.