/// <summary> /// Enforce the manager to add/update cache from <see cref="CacheFactory"/> /// </summary> /// <param name="key"></param> /// <param name="factory"></param> /// <returns></returns> public async Task <CachedData> CacheAsync(string key, CacheFactory factory, bool lockData) { CachedData data = new CachedData(key); await data.Semaphore.WaitAsync(); CachedData caching = null; lock (lockObj) { if (Caching.ContainsKey(key)) { caching = Caching[key]; } else { data.Lock(); Caching.Add(key, data); } } if (caching != null) { await caching.Semaphore.WaitAsync(); caching.Semaphore.Release(); return(caching); } using (var fs = AllocateTemporaryFile(factory, out var path)) { await factory.Factory(fs); data.Path = path; data.Size = fs.Length; TotalSize += fs.Length; TotalCount++; } CachedData last = null; lock (lockObj) { Caching.Remove(key); if (Caches.ContainsKey(key)) { last = Caches[key]; } data.Disposed += DataOnDisposed; Caches[key] = data; } last?.Dispose(); CheckCaches(); if (!lockData) { data.Unlock(); } data.Semaphore.Release(); Cached?.Invoke(this, new CachedEventArgs(data)); return(data); }