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

noc*_*ura 15 .net c# multithreading timer

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

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

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

Pet*_*hie 14

Joe Duffy(Microsoft的.NET Framework团队的并行扩展的开发主管,架构师和创建者)详细介绍了Windows上的并发编程 p 373

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


Mik*_*oud 6

如果非托管extern返回false,这实际上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; 
Run Code Online (Sandbox Code Playgroud)

请注意,ChangeTimerNative调用ChangeTimerQueueTimerWindows API函数,以便您可以阅读该文档,以了解它可能会失败的方式.

  • @PeterRitchie:很公平,我的意思是这不是你所知道的,而是你在这个世界的朋友中所知道的.我想这只会使我的回答无效吗? (3认同)

Ast*_*sti 5

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

由于 AppDomainTimerSafeHandle 继承自SafeHandleZeroOrMinusOneIsInvalid,因此 IsInvalid 是由它实现的 - 当非托管基础设施尝试创建计时器并最终得到一个 Safe-Handle 时,该 Safe-Handle 正在读取零或减一无效的定义。

所有案例都表明这种情况极不可能发生。