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

如何使用SemaphoreSlim实现仅首个线程执行Token刷新,其余线程异步释放?

调整思路

你当前的实现虽然通过双重检查避免了重复执行刷新逻辑,但所有等待的线程仍然需要依次排队获取锁、再判断过期状态,高并发下会产生不必要的排队开销。我们可以通过缓存正在执行的刷新任务的方式,让首个线程执行刷新时,其余线程直接等待该任务完成即可,无需排队进锁。

调整后的封装代码

private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
// 用volatile修饰保证多线程下的可见性,存储当前正在执行的刷新任务
private volatile Task _runningRefreshTask;

public async Task RunOnceAsync(Func<Task> worker)
{
    // 第一层检查:如果已有正在执行的刷新任务,直接等待完成即可,无需抢锁
    if (_runningRefreshTask != null)
    {
        await _runningRefreshTask;
        return;
    }

    await _semaphore.WaitAsync();
    try
    {
        // 第二层检查:抢锁成功后二次判断,避免多个线程同时通过第一层检查
        if (_runningRefreshTask != null)
        {
            await _runningRefreshTask;
            return;
        }

        // 首个进入锁的线程执行刷新任务,并存入缓存变量
        _runningRefreshTask = worker();
        await _runningRefreshTask;
    }
    finally
    {
        // 任务执行完成(无论成功失败)都清空缓存,释放锁
        _runningRefreshTask = null;
        _semaphore.Release();
    }
}

业务侧调用逻辑

基本无需修改,仅将原来的LockAsync替换为新的RunOnceAsync即可,原有双重检查可作为兜底保留:

if (!string.IsNullOrEmpty(UserSettings.Token) && !isWithoutRefresh)
{
    if (UserSettings.Expires < ConvertToTimestamp(DateTime.UtcNow.AddMinutes(2)))
    {
        await _locker.RunOnceAsync(async () =>
        {
            if (UserSettings.Expires < ConvertToTimestamp(DateTime.UtcNow.AddMinutes(2)))
            {
                if (Role.Guest.Equals(UserSettings.Role)
                    && !string.IsNullOrEmpty(UserSettings.Email))
                {
                    //TODO: initialize guest session
                }
                else
                {
                    await RefreshToken(httpClient);
                    await AlertService.ShowAsync("Odswiezony");
                }
            }
        });
    }
}

效果说明

  • 仅首个触发刷新的线程会进入锁执行刷新逻辑
  • 其余同时触发刷新的线程不需要排队抢锁,直接等待同一个刷新任务完成后同步释放
  • 刷新任务无论执行成功还是失败,都会清空缓存,下次Token过期时可正常触发新的刷新流程
  • 保留了双重检查兜底,不会出现重复刷新、漏刷新的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 20:06:03