你如何从s preading到所有的类prevent IDisposable的? [英] How do you prevent IDisposable from spreading to all your classes?

查看:124
本文介绍了你如何从s preading到所有的类prevent IDisposable的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说我有一组简单的类是这样的:

Let's say I have a simple set of classes like this:

class Bus
{
    Driver busDriver = new Driver();
}

class Driver
{
    Shoe[] shoes = { new Shoe(), new Shoe() };
}

class Shoe
{
    Shoelace lace = new Shoelace();
}

class Shoelace
{
    bool tied = false;
}

A 巴士有一个驱动器驱动器有两个 s,各有一个鞋带。一切都非常愚蠢的。

A Bus has a Driver, the Driver has two Shoes, each Shoe has a Shoelace. All very silly.

后来我决定在鞋带一些操作可能是多线程的,所以我加了的EventWaitHandle 的螺纹与沟通。因此,鞋带现在看起来是这样的:

Later I decide that some operation on the Shoelace could be multi-threaded, so I add an EventWaitHandle for the threads to communicate with. So Shoelace now looks like this:

class Shoelace
{
    private AutoResetEvent waitHandle = new AutoResetEvent(false);
    bool tied = false;
    // ... other stuff ..
}

实现IDisposable上鞋带

BUIT现在的FxCop会抱怨:关于鞋带实现IDisposable,因为它创建以下IDisposable的类型的成员:的EventWaitHandle

好吧,我实现了的IDisposable 鞋带和我的整洁的小类成为这个可怕的烂摊子:

Okay, I implement IDisposable on Shoelace and my neat little class becomes this horrible mess:

class Shoelace : IDisposable
{
    private AutoResetEvent waitHandle = new AutoResetEvent(false);
    bool tied = false;
    private bool disposed = false;

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

    ~Shoelace()
    {
        Dispose(false);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                if (waitHandle != null)
                {
                    waitHandle.Close();
                    waitHandle = null;
                }
            }
            // No unmanaged resources to release otherwise they'd go here.
        }
        disposed = true;
    }
}

或者因为(正如刚才提意见)鞋带本身没有非托管资源,我可能会使用简单的处置执行而不需要处置(布尔)和析构函数:

Or (as pointed out by commenters) since Shoelace itself has no unmanaged resources, I might use the simpler dispose implementation without needing the Dispose(bool) and Destructor:

class Shoelace : IDisposable
{
    private AutoResetEvent waitHandle = new AutoResetEvent(false);
    bool tied = false;

    public void Dispose()
    {
        if (waitHandle != null)
        {
            waitHandle.Close();
            waitHandle = null;
        }
        GC.SuppressFinalize(this);
    }
}

在恐怖眼睁睁的看着IDisposable的小号$ P $垫

右键就是这样固定的。但是,现在的FxCop会抱怨创建一个鞋带,所以必须的IDisposable 太。

Watch in horror as IDisposable spreads

Right that's that fixed. But now FxCop will complain that Shoe creates a Shoelace, so Shoe must be IDisposable too.

驱动器创建驱动器必须是的IDisposable 。 和巴士创建驱动器巴士必须的IDisposable 等等。

And Driver creates Shoe so Driver must be IDisposable. and Bus creates Driver so Bus must be IDisposable and so on.

突然,我的小改动鞋带引起了我很多的工作,我的老板是想知道我为什么要签巴士来进行更改鞋带

Suddenly my small change to Shoelace is causing me a lot of work and my boss is wondering why I need to checkout Bus to make a change to Shoelace.

你怎么prevent这个S 的IDisposable 的$ P $垫,但还是确保您的非托管的对象是妥善处理?

How do you prevent this spread of IDisposable, but still ensure that your unmanaged objects are properly disposed?

推荐答案

您不能真正preventIDisposable的从s preading。有些课程需要处理,如的AutoResetEvent ,而最有效的方法是做到这一点的的Dispose()方法来避免终结的开销。但这种方法必须以某种方式调用,因此完全按照你的榜样封装或包含IDisposable接口的类来处置这些,所以他们必须要一次性为好,等等,以避免它是唯一的方式:

You can't really "prevent" IDisposable from spreading. Some classes need to be disposed, like AutoResetEvent, and the most efficient way is to do it in the Dispose() method to avoid the overhead of finalizers. But this method must be called somehow, so exactly as in your example the classes that encapsulate or contain IDisposable have to dispose these, so they have to be disposable as well, etc. The only way to avoid it is to:

  • 避免使用IDisposable的类在可能的情况,锁定或等待在单个地方的事件,让昂贵的资源在一个地方,等
  • 创建它们只有当你需要他们,只是后处置他们(使用的模式)
  • avoid using IDisposable classes where possible, lock or wait for events in single places, keep expensive resources in single place, etc
  • create them only when you need them and dispose them just after (the using pattern)

在某些情况下的IDisposable可以忽略,因为它支持可选的情况下。例如,WaitHandle的实现IDisposable支持命名的互斥体。如果名字没有被使用,Dispose方法不执行任何操作。 MemoryStream的是另外一个例子,它不使用的系统资源和它的处置的实施也什么都不做。关于非托管资源是否正在使用或不小心的思维方式指导。因此,可以检查可用来源为.NET库或使用反编译器。

In some cases IDisposable can be ignored because it supports an optional case. For example, WaitHandle implements IDisposable to support a named Mutex. If a name is not being used, the Dispose method does nothing. MemoryStream is another example, it uses no system resources and its Dispose implementation also does nothing. Careful thinking about whether an unmanaged resource is being used or not can be instructional. So can examining the available sources for the .net libraries or using a decompiler.

这篇关于你如何从s preading到所有的类prevent IDisposable的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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