/// <inheritdoc/> public ValueTask <TScope?> FindByIdAsync(string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { throw new ArgumentException(SR.GetResourceString(SR.ID0195), nameof(identifier)); } var parameters = new { Method = nameof(FindByIdAsync), Identifier = identifier }; if (_cache.TryGetValue(parameters, out TScope? scope)) { return(new ValueTask <TScope?>(scope)); } return(new ValueTask <TScope?>(ExecuteAsync())); async Task <TScope?> ExecuteAsync() { if ((scope = await _store.FindByIdAsync(identifier, cancellationToken)) is not null) { await AddAsync(scope, cancellationToken); } await CreateEntryAsync(parameters, scope, cancellationToken); return(scope); } }
/// <summary> /// Retrieves a scope using its unique identifier. /// </summary> /// <param name="identifier">The unique identifier associated with the scope.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <returns> /// A <see cref="ValueTask{TResult}"/> that can be used to monitor the asynchronous operation, /// whose result returns the scope corresponding to the identifier. /// </returns> public ValueTask <TScope> FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); } var parameters = new { Method = nameof(FindByIdAsync), Identifier = identifier }; if (_cache.TryGetValue(parameters, out TScope scope)) { return(new ValueTask <TScope>(scope)); } async Task <TScope> ExecuteAsync() { if ((scope = await _store.FindByIdAsync(identifier, cancellationToken)) != null) { await AddAsync(scope, cancellationToken); } await CreateEntryAsync(parameters, scope, cancellationToken); return(scope); } return(new ValueTask <TScope>(ExecuteAsync())); }
/// <summary> /// Retrieves a scope using its unique identifier. /// </summary> /// <param name="identifier">The unique identifier associated with the scope.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <returns> /// A <see cref="ValueTask{TResult}"/> that can be used to monitor the asynchronous operation, /// whose result returns the scope corresponding to the identifier. /// </returns> public ValueTask <TScope> FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier)); } var parameters = new { Method = nameof(FindByIdAsync), Identifier = identifier }; if (_cache.TryGetValue(parameters, out TScope scope)) { return(new ValueTask <TScope>(scope)); } async Task <TScope> ExecuteAsync() { if ((scope = await _store.FindByIdAsync(identifier, cancellationToken)) != null) { await AddAsync(scope, cancellationToken); } using (var entry = _cache.CreateEntry(parameters)) { if (scope != null) { var signal = await CreateExpirationSignalAsync(scope, cancellationToken); if (signal == null) { throw new InvalidOperationException("An error occurred while creating an expiration signal."); } entry.AddExpirationToken(signal); } entry.SetSize(1L); entry.SetValue(scope); } return(scope); } return(new ValueTask <TScope>(ExecuteAsync())); }