SemaphoreSlim.Wait(CancellationToken)正确尝试/最终为OperationCancelledException?

SFu*_*n28 8 .net multithreading semaphore .net-4.0

当使用带有取消令牌的SemaphorSlim时,我应该如何构造try/finally,以便正确处理OperationCancelledException?在选项A中,取消令牌源会抛出OperationCancelledException但不会调用Release().在选项B中,取消令牌源会抛出OperationCancelledException,并且DOES会调用Release().

// option A:
_semaphorSlim.Wait( _cancellationTokenSource.Token );
try
{
     // do work here
}
finally
{
     _semaphorSlim.Release();
}


// option B:
try
{
     _semaphorSlim.Wait( _cancellationTokenSource.Token );
     // do work here
}
finally
{
     _semaphorSlim.Release();
}
Run Code Online (Sandbox Code Playgroud)

Ree*_*sey 7

选项A在这里更正确.你不需要ReleaseSemaphoreSlim时候取消,因为你从来没有真正掌握并增加其数量.因此,除非您的Wait呼叫实际成功,否则您不希望发布.

从这个使用Semaphore和SemaphoreSlim的MSDN页面:

程序员有责任确保线程不会释放信号量太多次.例如,假设信号量的最大计数为2,并且线程A和线程B都进入信号量.如果线程B中的编程错误导致它调用Release两次,则两个调用都会成功.信号量的计数已满,当线程A最终调用Release时,将抛出SemaphoreFullException.