我正在使用
SemaphoreSlim
作为我的锁定机制。在我的代码中,我不知道释放信号量哪个代码更有效?
这是信号量实例化:
private static readonly SemaphoreSlim _updateTokenLocker = new (1, 1);
第一个代码:
await _updateTokenLocker.WaitAsync();
try
{
if (DateTime.UtcNow >= _tokenExpirationDateTime.AddMinutes(-5))
{
var newToken = await GetTokenAsync();
return newToken;
}
}
finally
{
_updateTokenLocker.Release();
}
或此代码:
await _updateTokenLocker.WaitAsync();
if (DateTime.UtcNow >= _tokenExpirationDateTime.AddMinutes(-5))
{
var newToken = await GetTokenAsync();
_updateTokenLocker.Release();
return newToken;
}
显然第二个会更“高效”,因为它需要执行的操作更少,但这无关紧要,因为它是不正确的实现——在异常抛出的情况下,信号量不会被释放,所以你甚至不应该考虑它作为一个选项。
附言
try-finally
的区别应该可以忽略不计,尤其是与异步处理相比。
以下简单基准测试(来自 BenchmarkDotNet):
public class TryFinallyBench
{
private static readonly SemaphoreSlim _updateTokenLocker = new(1, 1);
[Benchmark]
public async Task Tryf()
{
await _updateTokenLocker.WaitAsync();
try
{
await Task.CompletedTask;
}
finally
{
_updateTokenLocker.Release();
}
}
[Benchmark]
public async Task NoTryf()
{
await _updateTokenLocker.WaitAsync();
await Task.CompletedTask;
_updateTokenLocker.Release();
}
}
在我的机器上:
方法 | 平均 | 错误 | 标准差 |
---|---|---|---|
试试 | 48.22 纳秒 | 0.785 纳秒 | 0.696 纳秒 |
不尝试 | 47.70 纳秒 | 0.953 纳秒 | 0.891 纳秒 |