大讨论!给我一个用try finally的理由,先! (200分)

  • 主题发起人 主题发起人 com
  • 开始时间 开始时间
世风日下
都不看问题就乱说话[:(!]
 
to com:
你所例举的是一种简单且特殊的情况:只有一层,而且except 里不 raise,
你考虑一下比较复杂的情形,例如:
try
...
try
....
try
......//可能还有许多层
try
....
except
....
raise
//自己不处理,有总管呢,但必须报错
end;
......
finally
...
try
...
except
....
raise
end;
end
finally
...
end;
except
on E:... do ShowError...
on E:... do ....
end
大多数实际应用的程序恐怕都比上面的模式要复杂,finally存在的必要性就显而易见了。
 
心平气和些。让我们先分析 com 最早的例子:
for i := 0 to 99999999 do
try
if 'asdfkl;jaskl;dfjaskl;dfjl;' = 'asdfklasjfsh' then
ShowMessage('adf');
finally
end;

他省略了 begin 和 end,实际上他代码等价于:
for i := 0 to 99999999 do begin
try
if 'asdfkl;jaskl;dfjaskl;dfjl;' = 'asdfklasjfsh' then
ShowMessage('adf');
finally
end;
end;

按照 Object Pascal 中的定义,程序只要离开用 try ... finally 保护起来的部分,
就必须执行finally...end 之间的部分。因此com的程序实际上做了 99999999 次(空)调用。

而 except 不是强制调用的,是先监测是否存在 exception,所以,如果换 try ... except
实际上做了 99999999 次(空)监测。

调用比监测大2-3倍是正常的。
在我的机器上 99999999 次调用为 4927, 相同次数的监测是 2043。

如果我们稍微修改成这样:
try
for i := 0 to 99999999 do begin
if 'asdfkl;jaskl;dfjaskl;dfjl;' = 'asdfklasjfsh' then
ShowMessage('adf');
end;
finally
end;

这时程序的意思是:99999999 次循环加一个 finally(一次调用),
换成 except 的话就是 99999999 次循环加一个 except (一次监测)。

在我的机器上 finally 为 550,except 是 370,而什么都不用的话是360。
所以,你看多一次监测多不了什么开销,而多一次调用开销大得多。

这就是 com 所举例的程序为什么效率相差很大的原因,它用 99999999 来放大了调用和检
测的区别,倒是一个不错的例子,但是实际应用中,还是用我后面修改过的用法比较常见。
(还有一个教训就是:省略 begin end 的时候要小心些)

最后,给一个 try - except - finally 经典用法:
Obj:= TSomeType.Create;
try
try
Obj.Something;
except
HandleError;
end;
finally
Obj.Free;
end;

Delphi 不能象 Java 那样 except, finally 混用:
try {
......
}
catch(Throwable e){
......
}
finally {
......
}
 
呵呵……OVER?
 
Y老大毕竟是Y老大
 
建议大家看看<WINDOWS核心编程>的第五部份

第五部分 结构化异常处理
第23章 结束处理程序 565
23.1 通过例子理解结束处理程序 566
23.2 Funcenstein1 566
23.3 Funcenstein2 566
23.4 Funcenstein3 568
23.5 Funcfurter1 568
23.6 突击测验:FuncaDoodleDoo 569
23.7 Funcenstein4 570
23.8 Funcarama1 571
23.9 Funcarama2 572
23.10 Funcarama3 572
23.11 Funcarama4:最终的边界 573
23.12 关于finally块的说明 574
23.13 Funcfurter2 575
23.14 SEH结束处理示例程序 576
第24章 异常处理程序和软件异常 578
24.1 通过例子理解异常过滤器和异常处理
程序 578
24.1.1 Funcmeister1 578
24.1.2 Funcmeister2 579
24.2 EXCEPTION_EXECUTE_HANDLER 580
24.2.1 一些有用的例子 581
24.2.2 全局展开 583
24.2.3 暂停全局展开 585
24.3 EXCEPTION_CONTINUE_
EXECUTION 586
24.4 EXCEPTION_CONTINUE_
SEARCH 588
24.5 Get Exception Code 589
24.6 Get Exception Information 592
24.7 软件异常 595
第25章 未处理异常和C++异常 598
25.1 即时调试 600
25.2 关闭异常消息框 601
25.2.1 强制进程终止运行 601
25.2.2 包装一个线程函数 601
25.2.3 包装所有的线程函数 601
25.2.4 自动调用调试程序 602
25.3 程序员自己调用UnhandledException
Filter 602
25.4 UnhandledExceptionFilter函数的一些
细节 603
25.5 异常与调试程序 604
25.6 C++异常与结构性异常的对比 618

而Macro Cantu也在他的书中说过,try...finally的开销比try..except的小
但具体怎么样我也不大记得了,好象是在<delphi4技术内幕>这本书里讲的。
 
存在必有存在的理由。
 
try finally 耗时 1900 毫秒
try except 耗时 570 毫秒
没有try 耗时 130 毫秒

(1900-130) / 99999999 = ...
一个try ... finally...就占用那么一点时间,也值得大惊小怪吗?
 
上面诸君
均值得我敬仰
我必当勤奋学之
他日能所不能
 
按照Windows的说法:
except:有错的话,立即写到标准错误设备,而不会等到缓冲区添满或程序员接受到清楚命令;
finally:则要调用;
 
上面的各位大侠,
个个无比利害,
小弟我佩服无比,
看来我的前途漫漫
 
听课!......佩服!
 
try...except只能在产生异常的情况下才能释放
而try..finally不管有没有异常最终都释放资源
 
上课中.........
 
老大,可是很多时候计算机的速度不时关键啊!!!
你难道不能还会让用户在使用的时候时不时的蹦出一句
XXX ERROR IN ADDRESS —#*……!·
用户那里知道你的程序那里出了错呢!
要是不把那些异常做掉,妈的, 你的东西还拿的出去啊!!!
尤其是搞数据库的时候,比如,窗体上放个编辑框让你输入整数,你难道还要让用户
看那句“XXX is not valid integer"!!!!!!
 
yysun分析得很好,在循环中使用try本来就不是一件好事,
正确的做法应该是将循环放到try块中而不是将try块放到循环中。
 
Y老大毕竟是Y老大
 
YY孙毕竟是YY孙, 各位DFW无出其右。[:)]
xianjun的观点也很有道理。希望com兄心平气和地想想。
 
受不了了,搞什么嘛!
不懂就问,别人说了还不懂,那就没招了!
try ...finally 和try ... except还比较?
 
我们好无聊
 
后退
顶部