Подтвердить что ты не робот

Возвращает ли Timer.Change() значение false?

В классе .NET System.Threading Timer есть несколько перегруженных методов Change(), которые возвращают "true, если таймер был успешно обновлен, иначе false".

Ссылка: http://msdn.microsoft.com/en-us/library/yz1c7148.aspx

Действительно ли этот метод возвращает false? Что может заставить это вернуть false?

4b9b3361

Ответ 1

Джо Даффи (ведущий разработчик, архитектор и основатель Parallel Расширения для команды .NET Framework в Microsoft), подробно описанные в параллельном программировании на Windows p373

Обратите внимание, что хотя Change вводится как возвращающий bool, он фактически никогда не вернет ничего, кроме true. Если есть проблема с изменением таймера - например, целевой объект, который уже был удален, - будет выведено исключение.

Ответ 2

Это может фактически вернуть значение false, если неуправляемый extern ChangeTimerNative должен был возвращать false. Однако это ужасно маловероятно.

Обратите внимание на код Microsoft:

bool status = false;
bool bLockTaken = false; 

// prepare here to prevent threadabort from occuring which could
// destroy m_lock state.  lock(this) can't be used due to critical
// finalizer and thinlock/syncblock escalation. 
RuntimeHelpers.PrepareConstrainedRegions();
try 
{ 
}
finally 
{
    do
    {
        if (Interlocked.CompareExchange(ref m_lock, 1, 0) == 0) 
        {
            bLockTaken = true; 
            try 
            {
                if (timerDeleted != 0) 
                    throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_Generic"));
                status = ChangeTimerNative(dueTime,period);
            }
            finally 
            {
                m_lock = 0; 
            } 
        }
        Thread.SpinWait(1);     // yield to processor 
    }
    while (!bLockTaken);
}
return status; 

ОБРАТИТЕ ВНИМАНИЕ, что ChangeTimerNative вызывает ChangeTimerQueueTimer функцию Windows API, чтобы вы могли прочитать эту документацию чтобы понять, как это может потерпеть неудачу.

Ответ 3

При проверке управляемого источника единственным случаем, в котором он возвращает false, является то, что если таймер AppDomain (если он не существует, он создан), представленный частным классом AppDomainTimerSafeHandle - имеет SafeHandle.IsInvalid установлен в true.

Так как AppDomainTimerSafeHandle наследует от SafeHandleZeroOrMinusOneIsInvalid, IsInvalid реализуется им - когда таймер пытается создать неуправляемую инфраструктуру и заканчивается с помощью Safe-Handle, которая считывается из определения "Нуль-ор-Минус-один-Is-Invalid".

Все случаи указывают на это крайне маловероятно.