/// <summary> /// Removes the single key resolver. /// When process of retrieving data for specific key is finished. /// Assigned process resolver is removed from the dictionary. /// NOTE: All registered requests should have access, already have a task. /// </summary> /// <param name="key">The key used to identify assigned resolver.</param> /// <param name="skr">The single key resolver instance to be removed.</param> /// <returns>Task with information when key is removed from dictionary.</returns> private async Task RemoveSingleKeyResolverAsync(TKey key, SingleKeyResolver skr) { await _lock.WaitAsync(); if (_dictionary.ContainsKey(key) && Object.ReferenceEquals(skr, _dictionary[key])) { _dictionary.Remove(key); } _lock.Release(); }
/// <summary> /// Method assigns process responsible of retrieving data for specified key. /// When method is called multiple times with same key /// only first dataSupplier function/task will be executed. /// </summary> /// <param name="key">The key, to identify external resource.</param> /// <param name="dataSupplier">The data supplier. Function responsible for retrieving data from external systems. /// Function can call cache, call external system, update cache.</param> /// <returns></returns> public async Task <TResult> TakeResourceAsync( TKey key, Func <TKey, Task <TResult> > dataSupplier) { SingleKeyResolver singleKeyResolver = null; await _lock.WaitAsync(); if (_dictionary.ContainsKey(key)) { singleKeyResolver = _dictionary[key]; } else { _dictionary[key] = singleKeyResolver = new SingleKeyResolver(key, this); } _lock.Release(); return(await singleKeyResolver.GetResourceAsync(dataSupplier).ConfigureAwait(false)); }