/// <summary> /// <see cref="IAuthoritionTokenService.GetToken(IAuthoritionComponent)"/> /// </summary> public TokenClaim GetToken(IAuthoritionComponent component) { var feature = component.GetFeatureCode(); //Try to remove the read-write lock from cache var locker = TokenCache.GetOrCreate(feature + "_locker", () => new ReaderWriterLockSlim(), null); TokenClaim Claim = null; do { Claim = locker.RetryReadWithLocker( () => TokenCache.Get <TokenClaim>(feature), READ_WAIT_LIMIT, DefaultOptionManagement.MaximumNumberOfRetries); //Return directly if the ticket exists if (Claim != null && Claim.Expires.HasValue) { return(Claim); } } while (!locker.TryEnterWriteLock(10)); //Read and write cannot acquire the state normally in the case of asynchronous, //so the process of acquiring the token is executed in a synchronous blocking manner. Claim = Task.Run(() => GetClaimTryToCache(TokenCache, feature, component)).Result; locker.ExitWriteLock(); return(Claim); }
/// <summary> /// /// </summary> /// <param name="Cache"></param> /// <param name="feature"></param> /// <param name="component"></param> /// <returns></returns> private static async Task <TokenClaim> GetClaimTryToCache(MemoryCache Cache, string feature, IAuthoritionComponent component) { CacheItemPolicy policy = null; var Claim = await component.ApplyToken(); //If the new token expiration time has expired, then the current token won't be cached. if (Claim.Expires.HasValue) { if (Claim.Expires.Value <= DateTime.Now) { Claim.Expires = null; } else { policy = new CacheItemPolicy { AbsoluteExpiration = Claim.Expires.Value } }; } Cache.Set(feature, Claim, policy); return(Claim); }