gpt4 book ai didi

c# - 仅针对托管资源的最小 IDisposable implimenation

转载 作者:可可西里 更新时间:2023-11-01 08:45:33 27 4
gpt4 key购买 nike

关于处理非托管资源的“标准完整”IDisposable 实现有很多信息 - 但实际上这种情况(非常)罕见(大多数资源已经被托管类包装).这个问题侧重于针对更常见的“仅限托管资源”情况的 IDisposable 的最小实现。

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

2:是否有任何理由添加完整的标准 IDisposable 实现(Dispose()Dispose(bool) Finalizer 等)超过所呈现的最小实现?

3:在这种最小情况下,使 Dispose 虚拟化(因为我们不提供 Dispose(bool))是否可行/明智?

4:如果这个最小的实现被一个完整的标准实现替换,包括一个(在这种情况下是无用的)终结器——这会改变 GC 处理对象的方式吗?有什么缺点吗?

5:该示例包括 Timer 和事件处理程序,因为这些情况特别重要,不要错过,因为未能处理它们将使对象保持事件状态并继续运行(thisTimer 的情况,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();
}
}

引用:
MSDN
SO: When do I need to manage managed resources
SO: How to dispose managed resource in Dispose() method in C#
SO: Dispose() for cleaning up managed resources

最佳答案

  1. 实现是正确的,没有问题,前提是没有派生类直接拥有非托管资源。

  2. 实现完整模式的一个很好的理由是“最小意外原则”。由于 MSDN 中没有权威文档描述这种更简单的模式,因此维护开发人员可能会有疑问 - 即使您觉得有必要问 StackOverflow :)

  3. 是的,在这种情况下,Dispose 可以是虚拟的。

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

.NET Framework 本身之外的绝大多数 IDisposable 类都是 IDisposable,因为它们拥有托管的 IDisposable 资源。他们很少直接持有非托管资源 - 只有在使用 P/Invoke 访问 .NET Framework 未公开的非托管资源时才会发生这种情况。

因此,推广这种更简单的模式可能有很好的理由:

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

  • 在所有其他情况下,绝大多数情况下,可以使用您的更简单的模式。

但除非 Microsoft 或其他权威来源积极推广它,否则我将继续使用完整的 IDisposable 模式。

关于c# - 仅针对托管资源的最小 IDisposable implimenation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18970742/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com