Ric*_*bob 11 c# dispose idisposable
IDisposable关于处理非托管资源的"标准完整" 实现有很多信息- 但实际上这种情况非常罕见(大多数资源已经被托管类包装).这个问题集中在更常见的"仅限托管资源"案例的IDisposable的最小实现上.
1:IDisposable下面的代码中的mimimal实现是否正确,是否存在问题?
2:是否有任何理由增加一个完整的标准IDisposable执行(Dispose(),Dispose(bool),Finalizer等)在最小的执行力度呈现的?
3:在这个极小的情况下,制作Dispose虚拟(因为我们没有提供Dispose(bool))是否可行/明智?
4:如果这个最小的实现被一个包含(在这种情况下是无用的)终结器的完整标准实现替换 - 这会改变GC处理对象的方式吗?有什么缺点吗?
5:示例包括Timer与事件处理程序,因为这些情况下,尤其重要的是不能错过的无法处理它们会保持对象活蹦乱跳(this在的情况下Timer,eventSource在事件处理程序的情况下),直到GC得到轮在释放他们是时候了.还有其他这样的例子吗?
class A : IDisposable {
private Timer timer;
public A(MyEventSource eventSource) {
eventSource += Handler
}
private void Handler(object source, EventArgs args) { ... }
public virtual void Dispose() {
timer.Dispose();
if (eventSource != null)
eventSource -= Handler;
}
}
class B : A, IDisposable {
private TcpClient tpcClient;
public override void Dispose() {
(tcpClient as IDispose).Dispose();
base.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
refs:
MSDN
SO:我什么时候需要管理托管资源
SO:如何在C#中的Dispose()方法中部署托管资源
:SO:Dispose()用于清理托管资源
实现是正确的,没有问题,前提是没有派生类直接拥有非托管资源.
实施完整模式的一个很好的理由是"最少惊喜的原则".由于MSDN中没有描述这种简单模式的权威文档,维护开发人员可能会有疑虑 - 即使你觉得有必要问StackOverflow :)
是的,在这种情况下,Dispose可以是虚拟的.
如果调用了Dispose并且正确实现了(即调用GC.SuppressFinalize),则不必要的终结器的开销可以忽略不计
IDisposable.NET Framework之外的绝大多数类都是IDisposable因为它们拥有托管IDisposable资源.他们很少直接持有非托管资源 - 这只有在使用P/Invoke访问.NET Framework未公开的非托管资源时才会发生.
因此,推广这种简单模式可能是一个很好的理由:
在极少数情况下使用非托管资源时,它们应该包装在一个密封的IDisposable包装类中,该类实现了终结器(如SafeHandle).因为它是密封的,所以这个类不需要完整的IDisposable模式.
在所有其他情况下,绝大多数情况下,您可以使用更简单的模式.
但除非并且直到微软或其他权威消息来源积极推广它,否则我将继续使用完整IDisposable模式.
| 归档时间: |
|
| 查看次数: |
1362 次 |
| 最近记录: |