The code you posted seems to work fine, because you're able to handle all possibilities. Try changing it somewhat though, so that there's an exception raised your code doesn't handle:
procedure TForm1.Button1Click(Sender: TObject);
begin
try
try
raise Exception.Create('42');
except
on E: EDivByZero do
ShowMessage('DivByZero');
end;
finally
ShowMessage('Finally');
end;
ShowMessage('Got here');
end;
Run this, and you'll see Finally
, then the exception for 42
, but no Got here
message. This is because the exception took you out of the current block, the stack is unwound, and the code from the end
of the finally to the end of the procedure never executes.
Move the final ShowMessage
call from where it is to inside the finally
and run again.
procedure TForm1.Button1Click(Sender: TObject);
begin
try
try
raise Exception.Create('42');
except
on E: EDivByZero do
ShowMessage('DivByZero');
end;
finally
ShowMessage('Finally');
ShowMessage('Got here');
end;
ShowMessage('Will never get here');
end;
You'll now see both calls to ShowMessage
in the finally
block, one after the other, but not the one after the finally
block's end;
. Code inside the finally
block is guaranteed to execute, while code beyond it may or may not.
To make it even more clear, the presence of the try..except
block can be removed:
procedure TForm1.Button1Click(Sender: TObject);
begin
try
raise Exception.Create('42');
finally
ShowMessage('Finally');
ShowMessage('Got here');
end;
ShowMessage('Will never get here');
end;
The entire purpose of the try..finally
block is to ensure that code inside the finally
section will execute before the procedure ends.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…