我们都知道如果是非托管资源是不被gc回收的,那么就需要我们自己重写析构函数,或者着实现IDispose接口,但是我们什么时候需要实现重写析构函数和实现IDispose接口,一般我们使用的非托管资源都已经实现了析构函数或者IDispose接口,比如SQLConnection,Font等,那还有什么需要我们自己来实现呢?我们自己写的类,会是非托管资源么?我们能自定义非托管资源么?

解决方案 »

  1.   

    所有不受CLR管理的资源都是非托管资源...你自己写的类不是资源,它可以调用托管资源和非托管资源,调用非托管资源则需要手动释放...释放非托管资源不应使用析构函数而应实现IDispose接口,因为析构函数只由GC调用不可控...
      

  2.   

    CLR执行的代码是托管代码,除此之外都是非托管代码
    托管代码的堆上的垃圾内存可由GC自动回收,非托管代码中堆上的垃圾内存必须程序员自己负责释放、回收
    在.NET的对象中实际上有两个用于释放资源的函数:Dispose和Finalize。Finalize的目的是用于释放非托管的资源,而Dispose是用于释放所有资源,包括托管的和非托管的。
      

  3.   

    你理解的没错。要释放的是.net无法管理的内存以及资源。比如文件操作的句柄,设备操作的句柄,GDI句柄等,这些应为.net已经封装过了。这些对应的类FileStream,SerialPort,Pen,SolidBrush等都实现了IDispose接口,会在垃圾回收的第一阶段执行Dispose的时候释放对系统核心资源的释放。如果你也使用到了。而且又用的不是系统的类,就需要自己释放。或者不一定是核心资源。你的某个类,封装了一些非托管资源的操作,如果你调用的方法分配了内存,而非托管那边的释放是等你调用某个例如FreeVirtualMemory的方法来释放,那就需要你在类中实现IDispose或析构函数在必要时候释放资源。
      

  4.   


    问一下,在你写过的代码中,会有多少需要实现DIspose的类,或者说在你的工作中,实现Dispose的情况会很多吗?能不能举个例子
      

  5.   

    可以用来避免忘记保存。
    public class Document : IDispose
    {
        public void Dispose()
        {
            SaveDocument();//避免忘记保存。
        }
    }
      

  6.   

    我们都知道如果是非托管资源是不被gc回收的,
    >> gc是会自动回收的,而且数据地址会改变 在c++中new的对象 都需要delete的,而且分配内存空间之后,就不会改变那么就需要我们自己重写析构函数 
    》》 不需要重写析构函数, 或者finalize,或者着实现IDispose接口,
    》》 可以实现dispose 接口,需要释放资源的时候 调接口但是我们什么时候需要实现重写析构函数和实现IDispose接口,一般我们使用的非托管资源都已经实现了析构函数或者IDispose接口,比如SQLConnection,Font
    这个是托管资源等,那还有什么需要我们自己来实现呢?使用非托管资源 比如windows api等我们自己写的类,会是非托管资源么?我们能自定义非托管资源么?
     
    unsafe

     里面非托管的指针啥的,如果要用指针的话 需要用fixed括起来 固定内存地址。
    )你还是找本书看看吧
      

  7.   

    我倒是非常愿意向jianuman 推荐一下《Effective C# 中文版 改善C#程序的50种方法》这本书。
      

  8.   

    我现在特别想知道的是,在大家的项目中,这个IDispose接口的实现率是多少。
      

  9.   

    IDispose不完全是释放资源,只是善后,如果有释放资源的操作也可以写在这里。我项目中,用到IDispose的2种情况,一个是释放未关闭的串口,另一个就是保存项目。
    事实上系统也是这个意思。你看看FileStream的Dispose方法。protected override void Dispose(bool disposing)
    {
        if (this._handle != HostNative.INVALID_HANDLE_VALUE)
        {
            lock (this)
            {
                if (this._handle != HostNative.INVALID_HANDLE_VALUE)
                {
                    try
                    {
                        this.Flush();
                    }
                    finally
                    {
                        if (this._ownsHandle)
                        {
                            PAL.File_Close(this._handle);
                        }
                        this._handle = HostNative.INVALID_HANDLE_VALUE;
                        this._canRead = false;
                        this._canWrite = false;
                        this._canSeek = false;
                        this._buffer = null;
                    }
                }
            }
        }
    }除了句柄赋值为无效,就只有Flush和Close了。真要问哪些情况使用这个接口,谁的项目都不如.net framework全面啊。你看看谁实现了IDispose不更好么 ^_^
      

  10.   

    IDispose和Form的CLosed类比更合适。关闭窗口的时候你要做点什么事。这个是类在呗释放前要做点什么事,可以是释放,也可以是保存,或是对象计数器-1等。