.NET中的对象垃圾收集事件

时间:2011-06-16 08:59:29

标签: .net events object garbage-collection

在一些具体的类实例被垃圾收集之前,有没有办法执行某些代码? 如果是,那是什么?

4 个答案:

答案 0 :(得分:1)

这是IDisposable模式。如果您希望动态更改Dispose运行的代码,请使用委托,例如

sealed class DelegatedDisposable : IDisposable {
    readonly Action disposer;
    void IDisposable.Dispose() { disposer(); }
    public DelegatedDisposable(Action onDispose) { disposer = onDispose; }
}

一个简单的包装器可能就足够了,你可以在其中存储要处理的对象:

sealed class WrappedDisposable<T> : IDisposable where T : IDisposable {
    readonly Action<T> onDispose;
    readonly T wrappedDisposable;
    public WrappedDisposable(T disposable, Action<T> callOnDispose) {
        if(disposable == null) throw new ArgumentNullException("disposable");
        if(callOnDispose == null) throw new ArgumentNullException("callOnDispose");
        wrappedDisposable = disposable;
        onDispose= callOnDispose;
    }
    void IDisposable.Dispose() { 
        try{ onDispose(wrappedDisposable); } 
        finally { wrappedDisposable.Dispose(); }
    }
}

如果您希望在对象被垃圾回收之前执行代码,则需要实现一个终结器,它在C#中看起来像一个私有构造函数,其名称前面有~。除非您手动管理本机资源(即导致本机malloc锁定分配或其他原因),否则通常不需要这样做。

答案 1 :(得分:0)

答案 2 :(得分:0)

这取决于您在处置之前想要做什么。有许多东西,比如长时间运行的操作,可以抛出异常等的操作,不推荐。你想触发一些执行OnDispose ..

你可以通过以下方式做到这一点,但我又不知道你想做什么,所以我不会推荐它。

我通常使用IDisposible来使用非托管资源并在using()中实例化该类并在那里执行操作。 在使用Dispose的范围之后将在使用块中调用我cna执行我的代码。 //有一个析构函数

~ MyClass() 
{
    //Do something here.
   // Cleaning up code goes here
}

这被翻译为

protected override void Finalize()
{
   try
   {
      // Do something here. Dont throw exception here.
      // Cleaning up .
   }
   finally
   {
      base.Finalize();
   }
}

如果你上课实施IDisposible,你可以在Dipose中获得额外的代码

protected virtual void Dispose(bool disposing)
    {
        //Do something before resource free up.
        if (disposing) 
        {
            // free managed resources
            if (managedResource != null)
            {
                managedResource.Dispose();
                managedResource = null;
            }
        }
        // free native resources if there are any.
        if (nativeResource != IntPtr.Zero) 
        {
            Marshal.FreeHGlobal(nativeResource);
            nativeResource = IntPtr.Zero;
        }
    }

答案 3 :(得分:0)

您可能也有兴趣阅读Shawn Farkas的精彩文章挖掘IDisposable http://msdn.microsoft.com/en-us/magazine/cc163392.aspx