在之前我看的写出优雅简明代码的论题集 -- Csharp(C#)篇[1]后续的评论中,看到了这么个结论:
“这点是却实,using如果出现异常不回收资源,使用using特别要注意这个问题”
其实上面的群论很清晰,using会展成一个try-finally,会在finally里显示调用object的Dispose()方法。
在这我想问的是:你既然都知道会展成什么,他凭什么就不会回收资源呢?难道不知道没有实现IDisposable的事不能using的吗?
先从msdn上捞了一段IDisposable的模板,改了改代码,原来的太复杂,为了凸出重点,我酌情给了删减:
using System; public class DisposeExample // The class constructor. public void ThrowException() protected virtual void Dispose(bool disposing) disposed = true; ~MyResource() |
这个代码不难读懂吧,在Main里,new了一个对象,让后再using里,call ThrowException()显式的抛出异常,关键是Dispose()方法会不会被调用呢?就是控制台能否打印出Dispose呢?
答案是肯定的。
结论:实现IDisposable接口是为了显式的(因为Finalize()不能显式的来call)确定的(Finalize()调用的不确定性)释放资源。将释放资源的操作放在Dispose()方法里完成,并且通过using来确保调用。至于dctor里Dispose(false)是因为我们不想让GC来释放资源,并且在Dispose()方法调用之后,不让GC去调用Finalize()(GC.SuppressFinalize(this);)。
PLUS:如果在new 对象的过程中发生了异常,则Dispose()方法是无法调用的。可以在ctor里调用ThrowException()试一下。