18

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

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

这个方法是否真的返回假?什么会导致它返回false?

4

3 回答 3

17

Joe Duffy(Microsoft .NET Framework 团队的 Parallel Extensions 开发负责人、架构师和创始人)在 Windows 上的并发编程第 373 页中进行了详细说明

请注意,虽然Change它的类型是返回 a bool,但它实际上永远不会返回任何东西,除非是 true。如果更改计时器出现问题——例如目标对象已被删除——将引发异常。

于 2012-09-25T16:46:04.203 回答
6

如果非托管外部返回 false,这实际上ChangeTimerNative可以返回 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; 

请注意调用ChangeTimerNativeWindows ChangeTimerQueueTimerAPI 函数,以便您可以阅读该文档以了解它可能会如何失败。

于 2012-09-25T16:46:33.993 回答
4

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

由于 AppDomainTimerSafeHandle 继承自SafeHandleZeroOrMinusOneIsInvalid,因此 IsInvalid 由它实现 - 当尝试由非托管基础设施创建计时器并以从零或减一是无效的定义中读取的安全句柄结束时。

所有案例都表明这是极不可能的。

于 2012-09-25T16:58:45.587 回答