Re[4]: Не понимаю поведение GC
От: FlyDN  
Дата: 07.11.05 23:34
Оценка:
Здравствуйте, Mab, Вы писали:

Mab>Здравствуйте, FlyDN, Вы писали:


FDN>>MSDN говорит.

Mab>Увы, но действительно говорит он неправду И приведенный пример подтвреждает это.

FDN>>То есть Timer в финализаторе не удаляет ссылку.

Mab>Да нет, Timer здесь не виноват. Это проблема дизайна. Зарегистрированный таймер получает ссылку от GC root-а. Соответственно, пока не будет Dispose он будет жить.

Странно рефлектором посмотрел код Timer.Dispose()

public void Dispose()
{
      this.timerBase.Dispose();
}


А вот код TimerBase.Dispose():


[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public void Dispose()
{
    bool flag1 = false;
    RuntimeHelpers.PrepareConstrainedRegions();
    try
    {
    }
    finally
    {
        do
        {
            if (Interlocked.CompareExchange(ref this.m_lock, 1, 0) == 0)
            {
                flag1 = true;
                try
                {
                            this.DeleteTimerNative(Win32Native.NULL);
                }
                finally
                {
                            this.m_lock = 0;
                }
            }
            Thread.SpinWait(1);
        }
        while (!flag1);
        GC.SuppressFinalize(this);
    }
}


А это код TimerBase.Finalize():
~TimerBase()
{
    bool flag1 = false;
    do
    {
        if (Interlocked.CompareExchange(ref this.m_lock, 1, 0) == 0)
        {
            flag1 = true;
            try
            {
                        this.DeleteTimerNative(Win32Native.NULL);
            }
            finally
            {
                        this.m_lock = 0;
            }
        }
        Thread.SpinWait(1);
    }
    while (!flag1);
}


Отличаются они только выделенным. Получается при вызове Dispose() ссылка на обьект обнуляется а после вызова Finalize() нет
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.