让我们说你有一些资源清理如下:这是C#.
try{/*stuff*/} catch(Exception e) {/*rollback logs etc.*/} finally{ if( context.Transaction != null ) context.Transaction.Dispose(); context.Connection.Close(); context.Connection.Dispose(); }
相反,这样做会更强大吗?
try{/*stuff*/} catch(Exception e) {/*rollback logs etc.*/} finally{ try{ if( context.Transaction != null ) context.Transaction.Dispose(); }catch(Exception e){/*logs*/} finally{ context.Connection.Close(); context.Connection.Dispose(); } }
这样,如果transaction.dispose在leat处设置为失败,则连接将有机会关闭.
相反,这样做会更强大吗?
多个使用块你会更好.
首先,你的捕获块将吃掉所有异常并且不需要(可以尝试...最后没有任何捕获).如果您可以处理(或增加值)异常,则仅使用catch.
但更好的是:
using (var resA = GetMeAResourceNeedingCleanUp()) using (var resB = new AnotherResourceNeedingCleanUpn(...)) { // Code that might throw goes in here. }
NB.一旦异常回退,最后块正在清理,抛出另一个异常可能会导致(充其量)混淆正在处理哪些异常.第二条准则:
不要从Dispose方法或终结器中抛出异常.如果您需要允许用户处理清理失败,请提供单独的Close方法,该方法可以报告其失败.
请注意,在"框架设计指南"(2 次 ED)有这样的(§9.4.1):
避免在Dispose(bool)中抛出异常,除非在包含进程已被破坏的临界情况下(泄漏,不一致的共享状态等).