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?
source to share
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;
}
source to share