Zoeken…


Syntaxis

  1. Try-except: try [statements] behalve [[[on E: ExceptionType do statement]] [else statement] | [verklaringen] einde;

    Probeer-eindelijk: probeer [statements] eindelijk [statements] einde;

Eenvoudig proberen ... tot slot een voorbeeld om geheugenlekken te voorkomen

Gebruik try - finally om lekkende bronnen (zoals geheugen) te voorkomen voor het geval er een uitzondering optreedt tijdens de uitvoering.

De onderstaande procedure slaat een string in een bestand op en voorkomt dat de TStringList lekt.

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;

Ongeacht of er een uitzondering optreedt tijdens het opslaan van het bestand, wordt SL vrijgegeven. Elke uitzondering gaat naar de beller.

Uitzonderlijk veilige terugkeer van een nieuw object

Wanneer een functie een object retourneert (in tegenstelling tot het gebruik van een object dat door de beller is doorgegeven), moet u oppassen dat een uitzondering niet tot gevolg heeft dat het object lekt.

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;

Naïeve programmeurs proberen misschien alle uitzonderingstypen te vangen en nil uit een dergelijke functie, maar dat is slechts een speciaal geval van de algemene ontmoedigde praktijk om alle uitzonderingstypen te vangen zonder ze te hanteren.

Probeer-eindelijk genest in probeer-behalve

Een try - finally blok kan worden genest in een try - except blok.

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

Als er een uitzondering optreedt in UseResource , wordt de uitvoering naar ReleaseResource . Als de uitzondering een EResourceUsageError , springt de uitvoering naar de uitzonderingshandler en roept HandleResourceErrors . Uitzonderingen van een ander type slaan de uitzonderingshandler hierboven over en borrelen door naar de volgende try - except de oproepstack blokkeren.

Uitzonderingen in AcquireResource of ReleaseResource zorgen ervoor dat de uitvoering naar de uitzonderingshandler gaat en het finally blok overslaat, hetzij omdat het bijbehorende try blok nog niet is ingevoerd of omdat het finally blok al is ingevoerd.

Probeer-behalve genest in try-eindelijk

Een try - except blok mag genest worden in een try - finally blok.

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

Als een EResourceUsageError optreedt in UseResource2 , gaat de uitvoering naar de uitzonderingshandler en wordt HandleResourceError . De uitzondering wordt als afgehandeld beschouwd, zodat de uitvoering doorgaat naar UseResource3 en vervolgens ReleaseResource .

Als er een uitzondering van een ander type komt voor in UseResource2 , dan is de uitzondering handler voorstelling zal hier niet van toepassing, zodat de uitvoering zal springen over de UseResource3 gesprek en ga direct naar het finally blok waar ReleaseResource zal worden genoemd. Daarna zal de uitvoering naar de volgende toepasselijke uitzonderingshandler springen als de uitzondering de call-stack oproept.

Als in het bovenstaande voorbeeld een uitzondering optreedt in een andere aanroep, wordt HandleResourceErrors niet aangeroepen. Dit komt omdat geen van de andere aanroepen plaatsvinden binnen het try blok dat overeenkomt met die uitzonderingshandler.

Probeer het eindelijk met 2 of meer objecten

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

Als u de objecten niet met nil buiten het try-finally blok initialiseert, als een van hen niet wordt gemaakt, zal er een AV op het slot-blok optreden, omdat het object niet nul zal zijn (omdat het niet was geïnitialiseerd) en zal een uitzondering veroorzaken.

De Free methode controleert of het object nul is, dus door beide objecten met nil initialiseren, voorkomt u fouten bij het vrijmaken ervan als ze niet zijn gemaakt.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow