18

.NET System.Threading Timerクラスには、「タイマーが正常に更新された場合はtrue、それ以外の場合はfalse」を返すオーバーロードされたChange()メソッドがいくつかあります。

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

このメソッドが実際にfalseを返すことはありますか?これがfalseを返す原因は何ですか?

4

3 に答える 3

17

Joe Duffy (Microsoft の Parallel Extensions to the .NET Framework チームの開発リーダー、アーキテクト、および創設者) は、Windows での並行プログラミングp 373で詳しく説明しています。

Changeを返すように入力されてboolいますが、実際には true 以外は返されないことに注意してください。ターゲット オブジェクトが既に削除されているなど、タイマーの変更に問題がある場合は、例外がスローされます。

于 2012-09-25T16:46:04.203 に答える
6

アンマネージ externChangeTimerNativeが false を返す場合、これは実際には 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は Windows API 関数を呼び出すChangeTimerQueueTimerので、そのドキュメントを読んでどのように失敗するかを把握できることに注意してください。

于 2012-09-25T16:46:33.993 に答える
4

管理対象ソースをチェックする際にfalseを返す唯一のケースは、プライベートクラスで表されるAppDomainタイマー(存在しない場合は作成されます)がtrueAppDomainTimerSafeHandleに設定されている場合です。SafeHandle.IsInvalid

AppDomainTimerSafeHandleはSafeHandleZeroOrMinusOneIsInvalidを継承しているため、IsInvalidはそれによって実装されます-アンマネージインフラストラクチャによってタイマーが作成されようとすると、定義Zero-Or-Minus-One-Is-Invalidから読み取っているSafe-Handleになります。

すべてのケースで、これは非常にありそうもないことを示しています。

于 2012-09-25T16:58:45.587 に答える