仅针对托管资源的最小IDisposable隐含 [英] Minimal IDisposable implimenation for managed resources only

查看:49
本文介绍了仅针对托管资源的最小IDisposable隐含的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于用于处置非托管资源的标准完整 IDisposable 实现,有很多信息-但实际上,这种情况非常少见(大多数资源已被托管类包装)。这个问题集中在IDisposable的最小实现上,这种情况对于更常见的仅受管资源情况而言。

There is a LOT of info around about the "standard full" IDisposable implementation for disposing of unmanaged resources - but in reality this case is (very) rare (most resources are already wrapped by managed classes). This question focuses on a mimimal implementation of IDisposable for the much more common "managed resources only" case.

1:下面代码中 IDisposable 的最小实现是否正确,是否存在问题?

1: Is the mimimal implementation of IDisposable in the code below correct, are there issues?

2:是否有理由添加完整的标准 IDisposable 实现( Dispose( ) Dispose(bool) Finalizer 等)在显示的最小限度内?

2: Is there any reason to add a full standard IDisposable implementation (Dispose(), Dispose(bool), Finalizer etc) over the minimal implimentation presented?

3:在这种最小的情况下,可以将 Dispose 虚拟化(因为我们没有提供) Dispose(bool))?

3: Is it OK/wise in this minimal case to make the Dispose virtual (since we are not providing Dispose(bool))?

4:如果此最小实现被包含以下内容的完整标准实现替换: (在这种情况下,没有用)终结器-这是否改变了GC处理对象的方式?有没有缺点?

4: If this minimal implementation is replaced with a full standard implementation that includes a (useless, in this case) finalizer - does this change how the GC handles the object? Are there any downsides?

5:该示例包括 Timer 和事件处理程序,因为这些情况尤其重要,不要因为无法处理而不能错过它们将使对象保持活动状态并踢(在 Timer eventSource 中,是 this code>(如果是事件处理程序),直到GC设法及时处置它们。还有其他例子吗?

5: The example includes Timer and event handlers as these cases are particularly important not to miss as failing to dispose them will keep objects alive and kicking (this in the case of Timer, eventSource in case of the event handler) until the GC gets round to disposing them in its time. Are there any other examples like these?

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();
    }   
}

refs:

MSDN

SO:我什么时候需要管理托管资源

SO:如何处理C#中的Dispose()方法中的托管资源

因此:Dispose()用于清理托管资源

推荐答案


  1. 实现是正确的,没有问题,只要没有派生类直接拥有不受管理的资源即可。

  1. The implementation is correct, there are no issues, provided no derived class directly owns an unmanaged resource.

实现完整模式的一个很好的理由是最少的惊喜。由于MSDN中没有描述这种简单模式的权威文档,因此维护开发人员可能会有疑问-甚至您都觉得有必要询问StackOverflow:)

One good reason to implement the full pattern is the "principle of least surprise". Since there is no authoritative document in MSDN describing this simpler pattern, maintenance developers down the line might have their doubts - even you felt the need to ask StackOverflow :)

是的,在这种情况下可以将Dispose虚拟化。

Yes it's OK for Dispose to be virtual in this case.

如果已调用Dispose并已正确实现,则不必要的终结器的开销可以忽略不计(即调用GC.SuppressFinalize)

The overhead of the unnecessary finalizer is negligible if Dispose has been called, and is correctly implemented (i.e. calls GC.SuppressFinalize)

绝大多数 IDisposable IDisposable ,因为它们拥有托管的 IDisposable 资源。对于他们来说,直接持有非托管资源的情况很少见-仅在使用P / Invoke访问.NET Framework未公开的非托管资源时才会发生。

The overwhelming majority of IDisposable classes outside the .NET Framework itself are IDisposable because they own managed IDisposable resources. It's rare for them to directly hold an unmanaged resource - this only happens when using P/Invoke to access unmanaged resources that aren't exposed by the .NET Framework.

因此推广这种简单模式可能有一个很好的论据:

Therefore there is probably a good argument for promoting this simpler pattern:


  • 在极少数情况下,使用非托管资源时,应该使用封装在实现终结器的密封 IDisposable 包装器类中(例如 SafeHandle )。因为是密封的,所以此类不需要完整的IDisposable模式。

  • In the rare cases that unmanaged resources are used, they should be wrapped in a sealed IDisposable wrapper class that implements a finalizer (like SafeHandle). Because it's sealed, this class doesn't need the full IDisposable pattern.

在绝大多数情况下,可以使用更简单的模式。

/ p>

In all other cases, the overwhelming majority, your simpler pattern could be used.

但是除非并且直到Microsoft或其他权威人士积极推广它,否则我将继续使用完整的 IDisposable 模式。

But unless and until Microsoft or some other authoritative source actively promotes it, I'll continue to use the full IDisposable pattern.

这篇关于仅针对托管资源的最小IDisposable隐含的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆