Событие сборки мусора объектов в .NET - PullRequest
0 голосов
/ 16 июня 2011

Есть ли способ выполнить некоторый код до того, как какой-то конкретный экземпляр класса будет собран мусором? Если да, что это?

Ответы [ 4 ]

1 голос
/ 16 июня 2011

Это шаблон 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 распределение блокировки или еще много чего).

0 голосов
/ 16 июня 2011

Возможно, вам также будет интересно прочитать отличную статью Шона Фаркаша, в которой можно найти IDisposable http://msdn.microsoft.com/en-us/magazine/cc163392.aspx

0 голосов
/ 16 июня 2011

это зависит от того, что вы хотите сделать до утилизации.Есть много вещей, таких как долго выполняющиеся операции, операции, которые могут генерировать исключения и т. Д., Которые не рекомендуются. Вы хотите запустить некоторое выполнение OnDispose.уверен, что вы хотите сделать, поэтому я не буду рекомендовать это.

У меня обычно есть IDisposible, где я использую неуправляемые ресурсы, создаю экземпляр класса в использовании () и выполняю там свои операции.После того, как область применения Dispose будет вызвана, в блоке using я могу выполнить свой код.// иметь деструктор

~ 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, вы можете иметь дополнительный бит кода в вас

0 голосов
/ 16 июня 2011
...