c# - 锁定语句 block 中的异步方法

标签 c#

我想将身份验证 token 放入缓存中,以便在多个应用程序域中使用。此 token 将每小时过期一次。当客户端无法使用 token 进行授权时,它会要求 token 生成服务生成一个新 token 。

我只希望第一个未成功通过身份验证的客户端发生这种重新生成,因此我采用了这样的锁定对象:

public async Task<Token> GenerateToken(Token oldToken)
{
    Token token;
    lock (lockObject)
    {
        var cachedToken = GetTokenFromCache();
        if (cachedToken == oldToken)
        {
            var authClient = new AuthClient(id, key);
            token = await authClient.AuthenticateClientAsync(); //KABOOM
            PutTokenInCache(token);
        }
        else
        {
            token = cachedToken;
        }
    }
    return token;
}

我的问题是 AuthClient 只有 async 方法,并且 async 方法在锁定语句 block 中是不允许的。我对 AuthClient 没有任何控制权,我可以在这里采用其他策略吗?

最佳答案

您可以使用 SemaphoreSlim 作为基本的异步就绪 lock 替换:

private readonly SemaphoreSlim lockObject = new SemaphoreSlim(1);
public async Task<Token> GenerateToken(Token oldToken)
{
  Token token;
  await lockObject.WaitAsync();
  try
  {
    var cachedToken = GetTokenFromCache();
    if (cachedToken == oldToken)
    {
      var authClient = new AuthClient(id, key);
      token = await authClient.AuthenticateClientAsync();
      PutTokenInCache(token);
    }
    else
    {
      token = cachedToken;
    }
  }
  finally
  {
    lockObject.Release();
  }
  return token;
}

关于c# - 锁定语句 block 中的异步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27231386/

相关文章:

C# 反射,将 MakeGenericMethod 与具有 'new()' 类型约束的方法一起使用

c# - 将匿名类型变量作为方法参数传递

c# - 以编程方式从自定义用户控件中的数据上下文访问数据

c# - c#中的相关路径

c# - 从另一个对象中获取 SignalR Core 中的 Hub 上下文

c# - C# 中不允许接口(interface)<动态> - 解决方法

c# - 使 asp.Net 应用程序支持浏览器的后退按钮的必须条件是什么?

c# - 为什么 WriteEntry 不适用于此 EventLog 源?

c# - 创建 ParseTree(不是 AST)

c# - NHibernate 4 升级 - 不能同时获取多个包