You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SemaphoreSlim释放方案对比:哪种实现方式更高效?

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();
}

这是SemaphoreSlim的标准正确用法:

  • finally块能确保无论try块内代码是正常执行、提前return还是抛出异常,信号量都会被释放,不会出现锁资源泄漏的情况。
  • 性能上几乎没有额外负担,finally的执行开销可以忽略不计。

第二种实现(存在致命问题)

await _updateTokenLocker.WaitAsync();
if (DateTime.UtcNow >= _tokenExpirationDateTime.AddMinutes(-5))
{
    var newToken = await GetTokenAsync();
    _updateTokenLocker.Release();
    return newToken;
}

这种写法完全不可用,存在严重的死锁风险:

  • 当if条件不满足时,代码不会执行Release(),信号量会一直被占用,后续所有调用WaitAsync()的线程都会永久等待,造成死锁。
  • 如果GetTokenAsync()抛出异常,同样不会执行Release(),锁资源直接泄漏。

关于效率的结论

两种写法在正常路径下的执行效率几乎没有差异,但第二种写法的正确性完全无法保障,根本没有讨论效率的意义。实际开发中必须使用第一种基于try/finally的写法。

内容的提问来源于stack exchange,提问作者Negin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:12:16