锁语句块中的异步方法

时间:2014-12-01 15:13:31

标签: c#

我想在缓存中放置一个身份验证令牌,可以在多个应用域中使用它。此令牌将每小时到期。当客户端无法使用令牌进行授权时,它会要求令牌生成服务生成新令牌。

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

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个方法。我对AuthClient没有任何控制权,我可以采用其他策略吗?

1 个答案:

答案 0 :(得分:8)

您可以使用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;
}