private async Task <T> GetFromCacheOrDownloadAsync(Uri uri, string fileName, bool preCacheOnly, CancellationToken cancellationToken, List <KeyValuePair <string, object> > initializerKeyValues) { StorageFile baseFile = null; T instance = default(T); if (_inMemoryFileStorage.MaxItemCount > 0) { var msi = _inMemoryFileStorage.GetItem(fileName, CacheDuration); if (msi != null) { instance = msi.Item; } } if (instance != null) { return(instance); } var folder = await GetCacheFolderAsync().ConfigureAwait(MaintainContext); baseFile = await folder.TryGetItemAsync(fileName).AsTask().ConfigureAwait(MaintainContext) as StorageFile; if (baseFile == null || await IsFileOutOfDateAsync(baseFile, CacheDuration).ConfigureAwait(MaintainContext)) { baseFile = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting).AsTask().ConfigureAwait(MaintainContext); try { instance = await DownloadFileAsync(uri, baseFile, preCacheOnly, cancellationToken, initializerKeyValues).ConfigureAwait(false); } catch (Exception) { await baseFile.DeleteAsync().AsTask().ConfigureAwait(false); throw; // re-throwing the exception changes the stack trace. just throw } } if (EqualityComparer <T> .Default.Equals(instance, default(T)) && !preCacheOnly) { instance = await InitializeTypeAsync(baseFile, initializerKeyValues).ConfigureAwait(false); if (_inMemoryFileStorage.MaxItemCount > 0) { var properties = await baseFile.GetBasicPropertiesAsync().AsTask().ConfigureAwait(false); var msi = new InMemoryStorageItem <T>(fileName, properties.DateModified.DateTime, instance); _inMemoryFileStorage.SetItem(msi); } } return(instance); }
/// <summary> /// Remove items based on provided keys /// </summary> /// <param name="keys">identified of the in-memory storage item</param> public void Remove(IEnumerable <string> keys) { foreach (var key in keys) { if (string.IsNullOrWhiteSpace(key)) { continue; } InMemoryStorageItem <T> tempItem = null; _inMemoryStorage.TryRemove(key, out tempItem); tempItem = null; } }
/// <summary> /// Add new item to in-memory storage /// </summary> /// <param name="item">item to be stored</param> public void SetItem(InMemoryStorageItem <T> item) { if (MaxItemCount == 0) { return; } _inMemoryStorage[item.Id] = item; // ensure max limit is maintained. trim older entries first if (_inMemoryStorage.Count > MaxItemCount) { var itemsToRemove = _inMemoryStorage.OrderBy(kvp => kvp.Value.Created).Take(_inMemoryStorage.Count - MaxItemCount).Select(kvp => kvp.Key); Remove(itemsToRemove); } }
/// <summary> /// Get item from in-memory storage as long as it has not ex /// </summary> /// <param name="id">id of the in-memory storage item</param> /// <param name="duration">timespan denoting expiration</param> /// <returns>Valid item if not out of date or return null if out of date or item does not exist</returns> public InMemoryStorageItem <T> GetItem(string id, TimeSpan duration) { InMemoryStorageItem <T> tempItem = null; if (!_inMemoryStorage.TryGetValue(id, out tempItem)) { return(null); } DateTime expirationDate = DateTime.Now.Subtract(duration); if (tempItem.LastUpdated > expirationDate) { return(tempItem); } _inMemoryStorage.TryRemove(id, out tempItem); return(null); }