假设我有以下例程:
function ReadFile(f : TFilename) : Boolean;
var
fs : TFileStream;
begin
Result := False;
try
fs := TFileStream.Create(f, ...);
try
// read file ...
Result := True;
finally
FreeAndNil(fs);
end;
except
// handle exceptions ...
end;
end;
Run Code Online (Sandbox Code Playgroud)
拥有except和finally转置有什么含义?我已经看到了很多与他们的职位左右逢源左右,但我还没有看到一个明确的解释这是适当的在哪些情况下(我仍然认为这是奇怪的是,在上述构建,该finally块执行后的except块!).
我也看过帖子表明混音try..except和try..finally积木并不是一个好主意.如果例程在正常操作中抛出异常(例如在某些Indy例程中),你怎么能避免它呢?
RE:如何正确编写Try..Finally..Except语句?
我仍然对OP的原始问题感到困惑.具体来说,该过程的最后一行(在try..finally..end之外)读取"Screen.Cursor:= crDefault".
我的理解是,一个try..except内提出的任何异常| finally..end块WILL的的"尝试","结束"后执行代码.
procedure TForm1.Button1Click(Sender: TObject);
var
Obj: TSomeObject;
begin
Screen.Cursor := crHourGlass;
Obj := TSomeObject.Create;
try
// do something
finally
Obj.Free;
end;
Screen.Cursor := crDefault;
end;
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,我没有看到为什么"Screen.Cursor:= crDefault"不会被执行的任何原因.如果我错了,请纠正我.
作为另一个例子,我编译了这一小段代码来帮助说明.运行代码时,将显示三(3)个ShowMessage()对话框.第一个"Exception Raised"和第二个"finally"和第三个"结束".
procedure TForm1.Button1Click(Sender: TObject);
begin
try
try
showMessage(format('%s', [12]));
except
showMessage('Exception raised');
end;
finally
showMessage('finally');
end;
showMessage('at end');
end;
Run Code Online (Sandbox Code Playgroud)
所以,我很困惑为什么他的"Screen.Cursor:= crDefault"没有被运行,原因是它的原始形式和代码.有人可以详细说明吗?
我有一个系统,它加载一些压缩到“.log”文件中的文本文件,然后使用多个线程将其解析为信息类,每个线程处理不同的文件并将解析的对象添加到列表中。该文件是使用 TStringList 加载的,因为它是我测试过的最快的方法。
文本文件的数量是可变的,但通常我必须在一次入侵中处理 5 到 8 个文件,范围从 50Mb 到 120Mb。
我的问题:用户可以根据需要多次加载 .log 文件,在其中一些进程之后,我在尝试使用 TStringList.LoadFromFile 时收到 EOutOfMemory 异常。当然,任何使用过 StringList 的人首先想到的是在处理大文本文件时不应该使用它,但是这个异常是随机发生的,并且在该过程至少成功完成一次之后(对象在新解析开始之前被销毁,因此除了一些小泄漏之外,内存可以正确检索)
我尝试使用textile 和TStreamReader,但它不如TStringList 快,而且这个过程的持续时间是这个功能最关心的问题。
我正在使用 10.1 Berlin,解析过程是一个简单的迭代,通过不同长度的线列表和基于线信息的对象构造。
本质上,我的问题是,是什么导致了这种情况,我该如何解决。我可以使用其他方式加载文件并读取其内容,但它必须与 TStringList 方法一样快(或更好)。
加载线程执行代码:
TThreadFactory= class(TThread)
protected
// Class that holds the list of Commands already parsed, is owned outside of the thread
_logFile: TLogFile;
_criticalSection: TCriticalSection;
_error: string;
procedure Execute; override;
destructor Destroy; override;
public
constructor Create(AFile: TLogFile; ASection: TCriticalSection); overload;
property Error: string read _error;
end;
implementation
{ TThreadFactory}
constructor TThreadFactory.Create(AFile: TLogFile; …Run Code Online (Sandbox Code Playgroud)