/// <summary> /// Asynchronously load data for the provided given key. /// </summary> /// <param name="key">Key to use for loading data</param> /// <returns> /// An object representing a pending operation /// </returns> public virtual IDataLoaderResult <T> LoadAsync(TKey key) { lock (_sync) { //once it enters the lock, it is guaranteed to exit the lock, as it does not depend on external code if (_cachedList != null) { if (_cachedList.TryGetValue(key, out var ret2)) { return(ret2); } } if (_list != null) { if (_list.TryGetValue(key, out var ret2)) { return(ret2); } if (_list.Count >= MaxBatchSize) { _list = new DataLoaderList(this); } } else { _list = new DataLoaderList(this); } var ret = new DataLoaderPair <TKey, T>(_list, key); _list.Add(key, ret); _cachedList?.Add(key, ret); return(ret); } }
/// <summary> /// Asynchronously load data for the provided given key. /// If the key is <see langword="null"/> then a <see cref="DataLoaderResult{T}"/> containing /// <see langword="null"/> will be immediately returned. /// </summary> /// <param name="key">Key to use for loading data</param> /// <returns> /// An object representing a pending operation /// </returns> public virtual IDataLoaderResult <T> LoadAsync(TKey key) { // dictionaries do not support keys with null values (null reference values or null value types), // so in this case bypass the data loader and return null if (key == null) { return(DataLoaderResult <T> .DefaultValue); } lock (_sync) { //once it enters the lock, it is guaranteed to exit the lock, as it does not depend on external code if (_cachedList != null) { if (_cachedList.TryGetValue(key, out var ret2)) { return(ret2); } } if (_list != null) { if (_list.TryGetValue(key, out var ret2)) { return(ret2); } if (_list.Count >= MaxBatchSize) { _list = new DataLoaderList(this); } } else { _list = new DataLoaderList(this); } var ret = new DataLoaderPair <TKey, T>(_list, key); _list.Add(key, ret); _cachedList?.Add(key, ret); return(ret); } }