Timer.Change()是否会返回false?

时间:2012-09-25 16:11:37

标签: c# .net multithreading timer

.NET System.Threading Timer类有几个重载的Change()方法,如果计时器成功更新,则返回“true”;否则为false。“

参考:http://msdn.microsoft.com/en-us/library/yz1c7148.aspx

这种方法实际上是否真的返回false?什么会导致它返回false?

3 个答案:

答案 0 :(得分:13)

Joe Duffy(Parallel的开发主管,架构师和创始人) Windows上的并发编程第373页中详细介绍了Microsoft .NET Framework团队的扩展

  

请注意,虽然Change被输入为返回bool,但它实际上永远不会返回任何内容而是真实的。如果更改计时器时出现问题 - 例如目标对象已被删除 - 将抛出异常。

答案 1 :(得分:6)

如果非托管extern ChangeTimerNative返回false,则实际上可以返回false。但是,这非常不可能。

请注意微软的代码:

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函数,以便您可以阅读该文档以了解它可能会如何失败。

答案 2 :(得分:3)

在检查托管源时,它返回false的唯一情况是,如果由私有类AppDomainTimerSafeHandle表示的AppDomain计时器(如果不存在,则创建它) - 具有SafeHandle.IsInvalid设置为true。

由于AppDomainTimerSafeHandle继承自SafeHandleZeroOrMinusOneIsInvalid,因此IsInvalid由它实现 - 当尝试由非托管基础架构创建计时器并最终得到一个安全句柄时,该句柄读取定义零或减号 - 酮,是 - 无效的。

所有案例都指出这种情况极不可能。