Zitat von
HeikoAdams:
committed
siehe Post #1
Schau dir aber dazu bitte meine beiden Codes aus Beitrag #4 an ... speziell die Streams und die zugehörigen Try-Finally.
Ein Resourcen-Schutzblock (Try-Finally) fängt
immer direkt nach der Resourcen-Beschaffung an,
um diese Resource auch richtig zu schützen/freizugeben.
Delphi-Quellcode:
{resource reservieren}
try
...
finally
{resource freigeben}
end;
und bei 2 Resourcen wäre es dann
Delphi-Quellcode:
{resource 1 reservieren}
try
...
{resource 2 reservieren}
try
...
finally
{resource 2 freigeben}
end;
...
finally
{resource 1 freigeben}
end;
Also muß es so gemacht werden, um einen korrekten Schutz zu gewährleisten:
Delphi-Quellcode:
SourceFile := TStream.Create(...);
try
DestFile := TStream.Create(...);
try
SourceFile.LoadFromFile(...);
DestFile.LoadFromFile(...);
...
finally
DestFile.Free;
end;
finally
SourceFile.Free;
end;
Folgendes geht nur unter zwei Annahmen:
- man kann der Resource einen prüfbaren Wert für "Resource nicht reserviert" zuweisen
- man kann ausschließen, daß beim Freigeben keine
Exception auftritt
Delphi-Quellcode:
DestFile := nil;
SourceFile := TFileStream.Create(aSourceFile, fmOpenRead or fmShareDenyWrite);
try
DestFile := TFileStream.Create(aDestFile, fmOpenRead or fmShareDenyWrite);
SourceFile.LoadFromFile(...);
DestFile.LoadFromFile(...);
...
finally
{if Assigned(DestFile) then} DestFile.Free; // aber dieses ist schon in .Free eingebaut
SourceFile.Free;
end;
Das
DestFile:=nil; wurde in vorherigen Beispielen nur aus logischer Sicht nach SourceFile:=TFileStream.Create verschoben und weil dieses keine Exteption auslösen kann (es sei denn der Stack ist vorher schon geschrottet, aber dann ist eh alles egal).
OK, wenn man zusätzlich noch ausschließen kann, daß keine
Exception beim Erstellen auftritt, dann ginge auch dieses, aber sowas ist beim Erstellen von Klassen eben nicht sichergestellt.
Delphi-Quellcode:
{resource 1 reservieren}
{resource 2 reservieren}
try
...
finally
{resource 2 freigeben}
{resource 1 freigeben}
end;