Asynchronous method in blocking-statement block

I want to place an authentication token in a cache where it can be used across multiple app domains. This token expires every hour. When the client cannot authorize with the token, it asks the token generation service to generate a new one.

I only want this regeneration to occur for the first client that failed to authenticate successfully, so I used the lock object like this:

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

      

My problem AuthClient

only has methods async

, and methods are async

not valid in blocking blocks. I have no control over AuthClient

, is there some other strategy I can use here?

+3


source to share


1 answer


You can use SemaphoreSlim

as a basic replacement for async-ready 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;
}

      

+8


source







All Articles