【发布时间】:2021-12-28 20:32:43
【问题描述】:
SemaphoreSlim 有一个WaitAsync() 方法,它采用CancellationToken。我希望在取消该令牌时释放信号量,但情况似乎并非如此。考虑下面的代码:
var tokenSource = new CancellationTokenSource();
var semaphore = new SemaphoreSlim(1, 1);
// CurrentCount is 1
await semaphore.WaitAsync(tokenSource.Token);
// CurrentCount is 0 as we'd expect
tokenSource.Cancel(); // Token is cancelled
for(var i = 0; i< 10; i++)
{
var c = semaphore.CurrentCount; // Current count remains 0, even though token was cancelled
await Task.Delay(1000);
}
即使在令牌被取消后,CurrentCount 仍为 0。我猜这是设计使然,但如果在取消令牌时不释放信号量,CancellationToken 究竟是用来做什么的?谢谢!
【问题讨论】:
-
CancellationToken用于取消等待。与获取的信号量没有业务往来。在您的代码中,当您调用WaitAsync时,它会立即返回,正如您所注意到的,因为允许 1 个线程拥有信号量。如果你用 0 个当前允许的线程初始化信号量,那么等待调用将真正等待。现在,如果您在其他线程上调用tokenSource.Cancel(),则等待返回,因为它在等待信号量期间监视您的令牌。 -
@cly 哦,这很有道理!非常感谢..