gpt4 book ai didi

c# - 是否真的需要只为托管资源实现处置模式

转载 作者:行者123 更新时间:2023-11-30 14:45:03 25 4
gpt4 key购买 nike

我仔细阅读了 this文章,它似乎明确指出在 IDisposable 实现的所有情况下都应该实现处置模式。我试图理解为什么我需要在我的类仅包含托管资源(即其他 IDisposable 成员或安全句柄)的情况下实现处置模式。为什么我不能写

class Foo : IDisposable
{
IDisposable boo;

void Dispose()
{
boo?.Dispose();
}
}

如果明确知道没有非托管资源并且没有必要从终结器调用 Dispose 方法,因为托管资源没有从终结器中释放?

更新:为了增加一些清晰度。讨论似乎归结为是否需要为每个实现 IDisposable 的公共(public)非密封基类实现处置模式的问题。但是,当没有非托管资源的基类不使用处置模式而具有非托管资源的子类使用此模式时,我找不到层次结构的潜在问题:

class Foo : IDisposable
{
IDisposable boo;

public virtual void Dispose()
{
boo?.Dispose();
}
}

// child class which holds umanaged resources and implements dispose pattern
class Bar : Foo
{
bool disposed;
IntPtr unmanagedResource = IntPtr.Zero;

~Bar()
{
Dispose(false);
}

public override void Dispose()
{
base.Dispose();
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (disposed)
return;

if (disposing)
{
// Free any other managed objects here.
//
}
// close handle

disposed = true;
}
}

// another child class which doesn't hold unmanaged resources and merely uses Dispose
class Far : Foo
{
private IDisposable anotherDisposable;

public override void Dispose()
{
base.Dispose();
anotherDisposable?.Dispose();
}
}

更重要的是,对我来说,当实现只对他们知道的事情负责时,关注点分离看起来更好。

最佳答案

这个

private class Foo : IDisposable
{
IDisposable boo;

public void Dispose()
{
boo?.Dispose();
}
}

完全没问题。原样

public sealed class Foo : IDisposable
{
IDisposable boo;

public void Dispose()
{
boo?.Dispose();
}
}

What could go wrong if I have public not sealed base class implemented as above with virtual Dispose method ?

来自docs :

Because the order in which the garbage collector destroys managed objects during finalization is not defined, calling this Dispose overload with a value of false prevents the finalizer from trying to release managed resources that may have already been reclaimed.

访问一个已经被回收的托管对象,或者在它被释放(可能被另一个终结器)后访问它的属性将导致在终结器中引发异常,即 bad :

If Finalize or an override of Finalize throws an exception, and the runtime is not hosted by an application that overrides the default policy, the runtime terminates the process and no active try/finally blocks or finalizers are executed. This behavior ensures process integrity if the finalizer cannot free or destroy resources.

所以如果你有:

   public  class Foo : IDisposable
{
IDisposable boo;

public virtual void Dispose()
{
boo?.Dispose();
}
}
public class Bar : Foo
{
IntPtr unmanagedResource = IntPtr.Zero;
~Bar()
{
this.Dispose();
}

public override void Dispose()
{
CloseHandle(unmanagedResource);
base.Dispose();
}

void CloseHandle(IntPtr ptr)
{
//whatever
}
}

~Bar -> Bar.Dispose() -> base.Dispose() -> boo.Dispose() 但是 boo 可能已经被 GC 回收了。

关于c# - 是否真的需要只为托管资源实现处置模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55712301/

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