Почему не вызывается Finalize для таймера
От: Mab Россия http://shade.msu.ru/~mab
Дата: 07.11.05 22:29
Оценка: 72 (7) +1
#Имя: FAQ.dotnet.timer.nofinalize
Здравствуйте, FlyDN, Вы писали:

FDN>В следующем коде "Finalizer" мы не увидим никогда, а почему?

Ответ на данный вопрос скрыт внути класса Timer. Если, скажем, сделать ему Dispose, то наблюдать вызов финалайзера мы начинаем в ождидаемом месте.

А дело все в том, что все созданные таймеры регистрируются в VM. Код из Рефлектора:
public Timer(TimerCallback callback)
{
      int num1 = -1;
      int num2 = -1;
      StackCrawlMark mark1 = StackCrawlMark.LookForMyCaller;
      this.TimerSetup(callback, this, (uint) num1, (uint) num2, ref mark1);
}

Далее:
private void TimerSetup(TimerCallback callback, object state, uint dueTime, uint period, ref StackCrawlMark stackMark)
{
      this.timerBase = new TimerBase();
      this.timerBase.AddTimer(callback, state, dueTime, period, ref stackMark);
}

И наконец
internal void AddTimer(TimerCallback callback, object state, uint dueTime, uint period, ref StackCrawlMark stackMark)
{
      if (callback == null)
      {
            throw new ArgumentNullException("TimerCallback");
      }
      _TimerCallback callback1 = new _TimerCallback(callback, state, stackMark);
      state = callback1;
      this.AddTimerNative(state, dueTime, period, ref stackMark);
      this.timerDeleted = 0;
}

Здесь
[MethodImpl(MethodImplOptions.InternalCall)]
private extern void AddTimerNative(object state, uint dueTime, uint period, ref StackCrawlMark stackMark);

так что для того, чтобы отследить вызов дальше, придется копаться в C++-коде виртуальной машины (например, в Роторе).

Итак, глобальная таблица косвенно держит делегат, который держит экземпляр Test.

Мораль: не пренебрегайте вызовом Dispose. Иначе некоторе финалайзеры у вас вызовутся лишь при app domain shutdown
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.