SemaphoreSlim.WaitAsync is not working. It jumps to return currentToken.AccessToken before the GetAccesTokenAsync call it's finished and throws NullException. I tried to use also AsyncLock, AsyncSemaphore and some other methods I read online but it seems like nothing it's working in my case.
public static class HttpClientHelper { #region members private static SemaphoreSlim semaphore = new SemaphoreSlim(1, 1); private static Token currentToken; #endregion public static string GetAuthorizeToken(ref HttpClient client, string username, string password) { GetToken(client, username, password); return currentToken.AccessToken; } private static async void GetToken(HttpClient client, string username, string password) { await semaphore.WaitAsync(); try { if (currentToken == null) { await GetAccesTokenAsync(client, username, password); } else if (currentToken.IsExpired) { await GetAccessTokenByRefreshToken(client); } } finally { semaphore.Release(); } } private static async Task<Token> GetAccesTokenAsync(HttpClient client, string username, string password) { List<KeyValuePair<string, string>> requestBody = new List<KeyValuePair<string, string>>(); requestBody.Add(new KeyValuePair<string, string>("Username", username)); requestBody.Add(new KeyValuePair<string, string>("Password", password)); requestBody.Add(new KeyValuePair<string, string>("grant_type", "password")); try { using (var urlEncodedContent = new FormUrlEncodedContent(requestBody)) { var httpResponse = await client.PostAsync(new Uri(client.BaseAddress + "/api/authentication/token"), urlEncodedContent); currentToken = await httpResponse.Content.ReadAsAsync<Token>(new[] { new JsonMediaTypeFormatter() }); } return currentToken; } catch (Exception e) { Logers.Log.Error($"Error while getting the access token {e}"); return null; } } }
GetTokenin a fire and forget way.GetToken()is a void async method which means that you can'tawaitit - and it will return immediately when it hits the firstawaitin it.