Возвращает ли Timer.Change() значение false?
В классе .NET System.Threading Timer есть несколько перегруженных методов Change(), которые возвращают "true, если таймер был успешно обновлен, иначе false".
Ссылка: http://msdn.microsoft.com/en-us/library/yz1c7148.aspx
Действительно ли этот метод возвращает false? Что может заставить это вернуть false?
Ответы
Ответ 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".
Все случаи указывают на это крайне маловероятно.