2017-10-18 92 views
2

鑑於以下代碼:等待() - 確保ManualResetEventSlim保證取消嗎?

CancellationTokenSource cts = new CancellationTokenSource(); 
ManualResetEventSlim mre = new ManualResetEventSlim(); 

和這兩個線程執行併發:

mre.Wait(cts.Token); 

cts.Cancel(); 
mre.Set(); 

保證拋出OperationCanceledException第一個(來電mre.Wait(cts.Token))或者它也有可能是只是退貨?

我的直覺說我應該期待發生(內部競賽條件)。 MSDN沒有給出答案,它只是說「在觀察CancellationToken時」。

我希望得到具體細節的答案,如何和爲什麼。

我想預先徵求意見,例如「您應該期望Cancel()Set()以任何順序同時/以任何順序發生,因此無論如何都是這兩種情況。我完全意識到這一點。

回答

1

有競爭條件,因爲Waitimplemented這樣的:

public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken) 
{ 
    ThrowIfDisposed(); 
    cancellationToken.ThrowIfCancellationRequested(); // an early convenience check 

    if (millisecondsTimeout < -1) 
    { 
     throw new ArgumentOutOfRangeException("millisecondsTimeout"); 
    } 

    if (!IsSet) 
    { 
    // lots of stuff here, not relevant 
    } 
    return true; 
} 

第二個線程(兩者取消,並將令牌)可能中斷cancellationToken.ThrowIfCancellationRequested()檢查和IsSet檢查之間的權利第一線。