public void AbsoluteExpirationExpiresInBackground() { var clock = new TestClock(); var cache = CreateCache(clock); var key = "myKey"; var value = new object(); var callbackInvoked = new ManualResetEvent(false); var options = new MemoryCacheEntryOptions() .SetAbsoluteExpiration(clock.UtcNow + TimeSpan.FromMinutes(1)) .RegisterPostEvictionCallback((subkey, subValue, reason, state) => { // TODO: Verify params var localCallbackInvoked = (ManualResetEvent)state; localCallbackInvoked.Set(); }, callbackInvoked); var result = cache.Set(key, value, options); Assert.Same(value, result); var found = cache.TryGetValue(key, out result); Assert.True(found); Assert.Same(value, result); clock.Add(TimeSpan.FromMinutes(2)); var ignored = cache.Get("otherKey"); // Background expiration checks are triggered by misc cache activity. Assert.True(callbackInvoked.WaitOne(TimeSpan.FromSeconds(30)), "Callback"); found = cache.TryGetValue(key, out result); Assert.False(found); Assert.Null(result); }
public MetadataReference GetMetadataReference(string path) { var cacheKey = _cacheKeyPrefix + path.ToLowerInvariant(); var metadata = _cache.Get<AssemblyMetadata>(cacheKey); if (metadata == null) { _logger.LogDebug(string.Format("Cache miss {0}", path)); using (var stream = File.OpenRead(path)) { var moduleMetadata = ModuleMetadata.CreateFromStream(stream, PEStreamOptions.PrefetchMetadata); metadata = AssemblyMetadata.Create(moduleMetadata); var options = new MemoryCacheEntryOptions(); options.ExpirationTokens.Add(new FileWriteTimeTrigger(path)); _cache.Set(cacheKey, metadata, options); } } var documentationFile = Path.ChangeExtension(path, ".xml"); if (File.Exists(documentationFile)) { return metadata.GetReference(new XmlDocumentationProvider(documentationFile)); } return metadata.GetReference(); }
/// <summary>Static constructor.</summary> static QueryCacheManager() { Cache = new MemoryCache(new MemoryCacheOptions()); DefaultMemoryCacheEntryOptions = new MemoryCacheEntryOptions(); CachePrefix = "Z.EntityFramework.Plus.QueryCacheManager;"; CacheTags = new ConcurrentDictionary<string, List<string>>(); }
public static void Main(string[] args) { // Runs several concurrent threads that access an item that periodically expires and is re-created. MemoryCache cache = new MemoryCache(new MemoryCacheOptions()); string key = "MyKey"; var options = new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMilliseconds(50)); var tasks = new List<Task>(); for (int threads = 0; threads < 100; threads++) { var task = Task.Run(() => { for (int i = 0; i < 110000; i++) { object value; if(!cache.TryGetValue(key, out value)) { // Fake expensive object creation. for (int j = 0; j < 1000000; j++) { } cache.Set(key, new object(), options); } } }); tasks.Add(task); } Console.WriteLine("Running"); Task.WaitAll(tasks.ToArray()); Console.WriteLine("Done"); }
/// <inheritdoc /> public ChunkTree GetOrAdd( string pagePath, Func<IFileInfo, ChunkTree> getChunkTree) { if (pagePath == null) { throw new ArgumentNullException(nameof(pagePath)); } if (getChunkTree == null) { throw new ArgumentNullException(nameof(getChunkTree)); } ChunkTree chunkTree; if (!_chunkTreeCache.TryGetValue(pagePath, out chunkTree)) { // GetOrAdd is invoked for each _ViewImport that might potentially exist in the path. // We can avoid performing file system lookups for files that do not exist by caching // negative results and adding a Watch for that file. var options = new MemoryCacheEntryOptions() .AddExpirationToken(_fileProvider.Watch(pagePath)) .SetSlidingExpiration(SlidingExpirationDuration); var file = _fileProvider.GetFileInfo(pagePath); chunkTree = file.Exists ? getChunkTree(file) : null; _chunkTreeCache.Set(pagePath, chunkTree, options); } return chunkTree; }
public void TestDefaultOptions() { var options = EntryOptions.Default; Assert.Equal(options.Behaviors, EntryBehaviors.Default); Assert.Null(options.AbsoluteExpiration); Assert.Null(options.AbsoluteExpirationRelativeToNow); Assert.Equal(options.SlidingExpiration, TimeSpan.FromMinutes(30)); Assert.True((options.Behaviors & EntryBehaviors.LookupCache) == EntryBehaviors.LookupCache); Assert.True((options.Behaviors & EntryBehaviors.SaveToCache) == EntryBehaviors.SaveToCache); Assert.True((options.Behaviors & EntryBehaviors.ReQueryWhenErrorCached) == EntryBehaviors.ReQueryWhenErrorCached); var cacheOptions = new MemoryCacheEntryOptions { AbsoluteExpiration = options.AbsoluteExpiration, AbsoluteExpirationRelativeToNow = options.AbsoluteExpirationRelativeToNow, SlidingExpiration = options.SlidingExpiration }; Assert.Equal(cacheOptions.SlidingExpiration, TimeSpan.FromMinutes(30)); Assert.Null(cacheOptions.AbsoluteExpiration); Assert.Null(cacheOptions.AbsoluteExpirationRelativeToNow); }
public CqrsMemoryCache() { _cache = new MemoryCache(new MemoryCacheOptions() { ExpirationScanFrequency = new TimeSpan(0, 0, 15, 0) }); _memoryCacheEntryOptions = new MemoryCacheEntryOptions() { SlidingExpiration = new TimeSpan(0, 0, 15, 0) }; }
/// <summary> /// Adds version query parameter to the specified file path. /// </summary> /// <param name="path">The path of the file to which version should be added.</param> /// <returns>Path containing the version query string.</returns> /// <remarks> /// The version query string is appended with the key "v". /// </remarks> public string AddFileVersionToPath(string path) { if (path == null) { throw new ArgumentNullException(nameof(path)); } var resolvedPath = path; var queryStringOrFragmentStartIndex = path.IndexOfAny(QueryStringAndFragmentTokens); if (queryStringOrFragmentStartIndex != -1) { resolvedPath = path.Substring(0, queryStringOrFragmentStartIndex); } Uri uri; if (Uri.TryCreate(resolvedPath, UriKind.Absolute, out uri) && !uri.IsFile) { // Don't append version if the path is absolute. return path; } string value; if (!_cache.TryGetValue(path, out value)) { var cacheEntryOptions = new MemoryCacheEntryOptions(); cacheEntryOptions.AddExpirationToken(_fileProvider.Watch(resolvedPath)); var fileInfo = _fileProvider.GetFileInfo(resolvedPath); if (!fileInfo.Exists && _requestPathBase.HasValue && resolvedPath.StartsWith(_requestPathBase.Value, StringComparison.OrdinalIgnoreCase)) { var requestPathBaseRelativePath = resolvedPath.Substring(_requestPathBase.Value.Length); cacheEntryOptions.AddExpirationToken(_fileProvider.Watch(requestPathBaseRelativePath)); fileInfo = _fileProvider.GetFileInfo(requestPathBaseRelativePath); } if (fileInfo.Exists) { value = QueryHelpers.AddQueryString(path, VersionKey, GetHashForFile(fileInfo)); } else { // if the file is not in the current server. value = path; } value = _cache.Set<string>(path, value, cacheEntryOptions); } return value; }
public void Set <T>(string key, T cachedValue, MemoryCacheEntryOptions options = null) where T : class { var entryOptions = new ms.MemoryCacheEntryOptions(); if (options != null) { entryOptions.SlidingExpiration = options.SlidingExpiration; entryOptions.RegisterPostEvictionCallback((entryKey, value, reason, substate) => options.Callback?.Invoke(entryKey.ToString(), value, reason, substate)); } _memoryCache.Set(key, cachedValue, entryOptions); }
public Task RenewAsync(string key, AuthenticationTicket ticket) { var options = new MemoryCacheEntryOptions(); var expiresUtc = ticket.Properties.ExpiresUtc; if(expiresUtc.HasValue) { options.SetAbsoluteExpiration(expiresUtc.Value); } options.SetSlidingExpiration(TimeSpan.FromHours(1)); // TODO: configurable. _cache.Set(key, ticket, options); return Task.FromResult(0); }
public async void SetCoreAsync_And_GetCoreAsync() { var cache = new ServiceCollection().AddMemoryCache().BuildServiceProvider().GetRequiredService <Microsoft.Extensions.Caching.Memory.IMemoryCache>(); var options = new Microsoft.Extensions.Caching.Memory.MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(2) }; var memoryCache = new Memory.MemoryCache("foobar", cache, options); await memoryCache.SetCoreAsync("key1", 123); Assert.Equal(123, cache.TryGetValue("key1", out object value) ? value : null); Assert.Equal(123, (await memoryCache.GetCoreAsync("key1", null)).Value); }
public void Set(string key, byte[] value, DistributedCacheEntryOptions options) { if (key == null) { throw new ArgumentNullException(nameof(key)); } var memoryCacheEntryOptions = new MemoryCacheEntryOptions(); memoryCacheEntryOptions.AbsoluteExpiration = options.AbsoluteExpiration; memoryCacheEntryOptions.AbsoluteExpirationRelativeToNow = options.AbsoluteExpirationRelativeToNow; memoryCacheEntryOptions.SlidingExpiration = options.SlidingExpiration; _memCache.Set(key, value, memoryCacheEntryOptions); }
internal CacheEntry( object key, object value, DateTimeOffset utcNow, DateTimeOffset? absoluteExpiration, MemoryCacheEntryOptions options, Action<CacheEntry> notifyCacheOfExpiration) { Key = key; Value = value; LastAccessed = utcNow; Options = options; _notifyCacheOfExpiration = notifyCacheOfExpiration; _absoluteExpiration = absoluteExpiration; PostEvictionCallbacks = options.PostEvictionCallbacks; }
public async Task<int> GetFeatureHashAsync(string featureId) { var cacheKey = FeatureHashCacheKey + ":" + featureId; bool enabled; if (!_memoryCache.TryGetValue(cacheKey, out enabled)) { enabled = (await _featureManager.GetEnabledFeaturesAsync()) .Any(x => x.Name.Equals(featureId)); var options = new MemoryCacheEntryOptions() .AddExpirationToken(_signal.GetToken(FeatureManager.FeatureManagerCacheKey)); _memoryCache.Set(cacheKey, enabled, options); } return enabled ? 1 : 0; }
public async Task<int> GetFeatureHashAsync() { int serial; if (_memoryCache.TryGetValue(FeatureHashCacheKey, out serial)) { return serial; } // Calculate a hash of all enabled features' name serial = (await _featureManager.GetEnabledFeaturesAsync()) .OrderBy(x => x.Name) .Aggregate(0, (a, f) => a * 7 + f.Name.GetHashCode()); var options = new MemoryCacheEntryOptions() .AddExpirationToken(_signal.GetToken(FeatureManager.FeatureManagerCacheKey)); _memoryCache.Set(FeatureHashCacheKey, serial, options); return serial; }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IMemoryCache cache) { var entryOptions = new Microsoft.Extensions.Caching.Memory.MemoryCacheEntryOptions(). SetPriority(CacheItemPriority.NeverRemove); cache.Set("kenobi", new CacheValue { Distance = "", message = new string[] { } }, entryOptions); cache.Set("skywalker", new CacheValue { Distance = "", message = new string[] { } }, entryOptions); cache.Set("sato", new CacheValue { Distance = "", message = new string[] { } }, entryOptions); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "MELI Challenge API V1"); }); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
public static TItem Set <TItem>(this FileCache cache, object key, TItem value, MemoryCacheEntryOptions options) { using (var entry = cache.CreateEntry(key)) { if (options != null) { entry.SetOptions(options); } entry.Value = value; if (cache.Get(key) != null) { cache.Persist <TItem>(entry); } } return(value); }
public static TItem Set <TItem>(this IMemoryCache cache, object key, TItem value, MemoryCacheEntryOptions options, IDropOutToken dropOutToken = null) { using (var entry = cache.CreateEntry(key)) { if (options != null) { entry.SetOptions(options); } entry.Value = value; entry.DropOutToken = dropOutToken; } return(value); }
public async Task ProcessAsync_FlowsEntryLinkThatAllowsAddingTriggersToAddedEntry() { // Arrange var id = "some-id"; var expectedContent = new DefaultTagHelperContent(); expectedContent.SetContent("some-content"); var tokenSource = new CancellationTokenSource(); var cache = new MemoryCache(new MemoryCacheOptions()); var cacheEntryOptions = new MemoryCacheEntryOptions() .AddExpirationToken(new CancellationChangeToken(tokenSource.Token)); var tagHelperContext = new TagHelperContext( allAttributes: new TagHelperAttributeList(), items: new Dictionary<object, object>(), uniqueId: id); var tagHelperOutput = new TagHelperOutput( "cache", new TagHelperAttributeList { { "attr", "value" } }, getChildContentAsync: useCachedResult => { TagHelperContent tagHelperContent; if (!cache.TryGetValue("key1", out tagHelperContent)) { tagHelperContent = expectedContent; cache.Set("key1", tagHelperContent, cacheEntryOptions); } return Task.FromResult(tagHelperContent); }); tagHelperOutput.PreContent.SetContent("<cache>"); tagHelperOutput.PostContent.SetContent("</cache>"); var cacheTagHelper = new CacheTagHelper(cache, new HtmlTestEncoder()) { ViewContext = GetViewContext(), }; var key = cacheTagHelper.GenerateKey(tagHelperContext); // Act - 1 await cacheTagHelper.ProcessAsync(tagHelperContext, tagHelperOutput); IHtmlContent cachedValue; var result = cache.TryGetValue(key, out cachedValue); // Assert - 1 Assert.Equal("HtmlEncode[[some-content]]", tagHelperOutput.Content.GetContent()); Assert.True(result); // Act - 2 tokenSource.Cancel(); result = cache.TryGetValue(key, out cachedValue); // Assert - 2 Assert.False(result); Assert.Null(cachedValue); }
/// <summary> /// Forces the absolute expiration. /// </summary> /// <param name="options">The options.</param> /// <param name="delay">The delay.</param> /// <returns>MemoryCacheEntryOptions.</returns> public static MemoryCacheEntryOptions ForceAbsoluteExpiration(this MemoryCacheEntryOptions options, TimeSpan delay) => options.AddExpirationToken(new CancellationChangeToken(new CancellationTokenSource(delay).Token));
// Internal for unit testing internal MemoryCacheEntryOptions GetMemoryCacheEntryOptions() { var options = new MemoryCacheEntryOptions(); if (ExpiresOn != null) { options.SetAbsoluteExpiration(ExpiresOn.Value); } if (ExpiresAfter != null) { options.SetAbsoluteExpiration(ExpiresAfter.Value); } if (ExpiresSliding != null) { options.SetSlidingExpiration(ExpiresSliding.Value); } if (Priority != null) { options.SetPriority(Priority.Value); } return options; }
internal static void AddIdentityToCache(Guid userId, ErpIdentity identity) { var options = new MemoryCacheEntryOptions(); options.SetAbsoluteExpiration(TimeSpan.FromMinutes(5)); cache.Set(userId.ToString(), identity, options); }
/// <summary> /// Initializes a new instance of the <see cref="MemoryCacheRegistration"/> class. /// </summary> /// <param name="name">The name.</param> /// <param name="entryOptions">The entry options.</param> /// <param name="builder">The builder.</param> /// <param name="cacheTags">The cache tags.</param> public MemoryCacheRegistration(string name, MemoryCacheEntryOptions entryOptions, CacheItemBuilder builder, params string[] cacheTags) : this(new StackTrace(), name, entryOptions, builder, null, cacheTags != null && cacheTags.Length > 0 ? (a, b) => cacheTags : (Func <object, object[], string[]>)null) { }
/// <summary> /// Sets the cache entry change expiration. /// </summary> /// <param name="options">The options.</param> /// <param name="cache">The cache.</param> /// <param name="key">The key.</param> /// <returns>MemoryCacheEntryOptions.</returns> public static MemoryCacheEntryOptions SetCacheEntryChangeExpiration(this MemoryCacheEntryOptions options, IMemoryCache cache, string key) { options.AddExpirationToken(MakeCacheEntryChangeToken(cache, new[] { key })); return(options); }
public void RemoveAndReAddFromCallbackWorks() { var cache = CreateCache(); var value = new object(); var obj2 = new object(); string key = "myKey"; var callbackInvoked = new ManualResetEvent(false); var options = new MemoryCacheEntryOptions(); options.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration() { EvictionCallback = (subkey, subValue, reason, state) => { Assert.Equal(key, subkey); Assert.Same(subValue, value); Assert.Equal(EvictionReason.Removed, reason); var localCallbackInvoked = (ManualResetEvent)state; cache.Set(key, obj2); localCallbackInvoked.Set(); }, State = callbackInvoked }); var result = cache.Set(key, value, options); Assert.Same(value, result); cache.Remove(key); Assert.True(callbackInvoked.WaitOne(TimeSpan.FromSeconds(30)), "Callback"); result = cache.Get(key); Assert.Same(obj2, result); }
/// <summary> /// Add a new state to the cache and set a custom cache item policy /// </summary> /// <param name="key"></param> /// <param name="state"></param> /// <param name="policy"></param> public void Add(string key, HandshakeState state, MemoryCacheEntryOptions options) { this.Cache.Set(key, state, options); }
public static TItem Set <TItem>(this IMemoryCache cache, object key, TItem value, MemoryCacheEntryOptions options) { using ICacheEntry entry = cache.CreateEntry(key); if (options != null) { entry.SetOptions(options); } entry.Value = value; return(value); }
/// <param name="cache">Must be thread safe.</param> public static async Task <TItem> AtomicGetOrCreateAsync <TItem>(this IMemoryCache cache, object key, MemoryCacheEntryOptions options, Func <Task <TItem> > factory) { if (cache.TryGetValue(key, out TItem value)) { return(value); } AsyncLock asyncLock; lock (AsyncLocksLock) { // If we have no dic for the cache yet then create one. if (!AsyncLocks.TryGetValue(cache, out Dictionary <object, AsyncLock> cacheDic)) { cacheDic = new Dictionary <object, AsyncLock>(); AsyncLocks.Add(cache, cacheDic); } if (!cacheDic.TryGetValue(key, out asyncLock)) { asyncLock = new AsyncLock(); cacheDic.Add(key, asyncLock); } } using (await asyncLock.LockAsync().ConfigureAwait(false)) { if (!cache.TryGetValue(key, out value)) { value = await factory.Invoke().ConfigureAwait(false); cache.Set(key, value, options); lock (AsyncLocksLock) { var cacheDic = AsyncLocks[cache]; // Note that if a cache is disposed, then the cleanup will never happen. This should not cause normally issues, but keep in mind. // Cleanup the evicted asynclocks. foreach (var toRemove in cacheDic.Keys.Where(x => !cache.TryGetValue(x, out _)).ToList()) { cacheDic.Remove(toRemove); } } } return(value); } }
private Task<CompilerCacheResult> CreateCacheEntry( string normalizedPath, Func<RelativeFileInfo, CompilationResult> compile) { TaskCompletionSource<CompilerCacheResult> compilationTaskSource = null; MemoryCacheEntryOptions cacheEntryOptions = null; IFileInfo fileInfo = null; Task<CompilerCacheResult> cacheEntry; // Safe races cannot be allowed when compiling Razor pages. To ensure only one compilation request succeeds // per file, we'll lock the creation of a cache entry. Creating the cache entry should be very quick. The // actual work for compiling files happens outside the critical section. lock (_cacheLock) { if (_cache.TryGetValue(normalizedPath, out cacheEntry)) { return cacheEntry; } fileInfo = _fileProvider.GetFileInfo(normalizedPath); if (!fileInfo.Exists) { var expirationToken = _fileProvider.Watch(normalizedPath); cacheEntry = Task.FromResult(new CompilerCacheResult(new[] { expirationToken })); cacheEntryOptions = new MemoryCacheEntryOptions(); cacheEntryOptions.AddExpirationToken(expirationToken); } else { cacheEntryOptions = GetMemoryCacheEntryOptions(normalizedPath); // A file exists and needs to be compiled. compilationTaskSource = new TaskCompletionSource<CompilerCacheResult>(); cacheEntry = compilationTaskSource.Task; } cacheEntry = _cache.Set<Task<CompilerCacheResult>>(normalizedPath, cacheEntry, cacheEntryOptions); } if (compilationTaskSource != null) { // Indicates that the file was found and needs to be compiled. Debug.Assert(fileInfo != null && fileInfo.Exists); Debug.Assert(cacheEntryOptions != null); var relativeFileInfo = new RelativeFileInfo(fileInfo, normalizedPath); try { var compilationResult = compile(relativeFileInfo); compilationResult.EnsureSuccessful(); compilationTaskSource.SetResult( new CompilerCacheResult(compilationResult, cacheEntryOptions.ExpirationTokens)); } catch (Exception ex) { compilationTaskSource.SetException(ex); } } return cacheEntry; }
/// <summary> /// Expire the cache entry if the given <see cref="IChangeToken"/> expires. /// </summary> /// <param name="options">The <see cref="MemoryCacheEntryOptions"/>.</param> /// <param name="expirationToken">The <see cref="IChangeToken"/> that causes the cache entry to expire.</param> /// <returns>The <see cref="MemoryCacheEntryOptions"/> so that additional calls can be chained.</returns> public static MemoryCacheEntryOptions AddExpirationToken( this MemoryCacheEntryOptions options, IChangeToken expirationToken !!) {
/// <summary> /// Initializes a new instance of the <see cref="MemoryCacheRegistration"/> class. /// </summary> /// <param name="name">The name.</param> /// <param name="entryOptions">The entry options.</param> /// <param name="builder">The builder.</param> /// <param name="cacheTags">The cache tags.</param> public MemoryCacheRegistration(string name, MemoryCacheEntryOptions entryOptions, CacheItemBuilder builder, Func <object, object[], string[]> cacheTags) : this(new StackTrace(), name, entryOptions, builder, null, cacheTags) { }
public object Set(object key, object value, MemoryCacheEntryOptions options) { return new object(); }
public object Set(object key, object value, MemoryCacheEntryOptions cacheEntryOptions) { throw new NotImplementedException(); }
private CompilerCacheResult CreateCacheEntry( string normalizedPath, Func<RelativeFileInfo, CompilationResult> compile) { CompilerCacheResult cacheResult; var fileInfo = _fileProvider.GetFileInfo(normalizedPath); MemoryCacheEntryOptions cacheEntryOptions; CompilerCacheResult cacheResultToCache; if (!fileInfo.Exists) { cacheResultToCache = CompilerCacheResult.FileNotFound; cacheResult = CompilerCacheResult.FileNotFound; cacheEntryOptions = new MemoryCacheEntryOptions(); cacheEntryOptions.AddExpirationToken(_fileProvider.Watch(normalizedPath)); } else { var relativeFileInfo = new RelativeFileInfo(fileInfo, normalizedPath); var compilationResult = compile(relativeFileInfo).EnsureSuccessful(); cacheEntryOptions = GetMemoryCacheEntryOptions(normalizedPath); // By default the CompilationResult returned by IRoslynCompiler is an instance of // UncachedCompilationResult. This type has the generated code as a string property and do not want // to cache it. We'll instead cache the unwrapped result. cacheResultToCache = new CompilerCacheResult( CompilationResult.Successful(compilationResult.CompiledType)); cacheResult = new CompilerCacheResult(compilationResult); } _cache.Set(normalizedPath, cacheResultToCache, cacheEntryOptions); return cacheResult; }
public object Set(object key, object value, MemoryCacheEntryOptions cacheEntryOptions) { if (key == null) { throw new ArgumentNullException(nameof(key)); } CheckDisposed(); CacheEntry priorEntry = null; var utcNow = _clock.UtcNow; DateTimeOffset?absoluteExpiration = null; if (cacheEntryOptions.AbsoluteExpirationRelativeToNow.HasValue) { absoluteExpiration = utcNow + cacheEntryOptions.AbsoluteExpirationRelativeToNow; } else if (cacheEntryOptions.AbsoluteExpiration.HasValue) { if (cacheEntryOptions.AbsoluteExpiration <= utcNow) { throw new ArgumentOutOfRangeException( nameof(MemoryCacheEntryOptions.AbsoluteExpiration), cacheEntryOptions.AbsoluteExpiration.Value, "The absolute expiration value must be in the future."); } absoluteExpiration = cacheEntryOptions.AbsoluteExpiration; } var entry = new CacheEntry( key, value, utcNow, absoluteExpiration, cacheEntryOptions, _entryExpirationNotification); var link = EntryLinkHelpers.ContextLink; if (link != null) { // Copy expiration tokens and AbsoluteExpiration to the link. // We do this regardless of it gets cached because the tokens are associated with the value we'll return. if (entry.Options.ExpirationTokens != null) { link.AddExpirationTokens(entry.Options.ExpirationTokens); } if (absoluteExpiration.HasValue) { link.SetAbsoluteExpiration(absoluteExpiration.Value); } } bool added = false; _entryLock.EnterWriteLock(); try { if (_entries.TryGetValue(key, out priorEntry)) { _entries.Remove(key); priorEntry.SetExpired(EvictionReason.Replaced); } if (!entry.CheckExpired(utcNow)) { _entries[key] = entry; entry.AttachTokens(); added = true; } } finally { _entryLock.ExitWriteLock(); } if (priorEntry != null) { priorEntry.InvokeEvictionCallbacks(); } if (!added) { entry.InvokeEvictionCallbacks(); } StartScanForExpiredItems(); return(value); }
/// <inheritdoc /> public IAndMemoryCacheBuilder WithEntry(object key, object value, MemoryCacheEntryOptions options) { this.MemoryCache.Set(key, value, options); return this; }
/// <summary> /// Gets a cache item policy. /// </summary> /// <param name="minutes">Absolute expiration time in x minutes</param> /// <returns></returns> private static MemoryCacheEntryOptions GetCacheEntryOptions(int minutes) { var cacheEntryOptions = new MemoryCacheEntryOptions() { Priority = CacheItemPriority.Normal, AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(minutes) //RemovedCallback = (item) => //{ // // dispose cached item at removal // var asDisposable = item.CacheItem as IDisposable; // if (asDisposable != null) // asDisposable.Dispose(); //} }; return cacheEntryOptions; }
private MemoryCacheEntryOptions GetMemoryCacheEntryOptions(string relativePath) { var options = new MemoryCacheEntryOptions(); options.AddExpirationToken(_fileProvider.Watch(relativePath)); var viewImportsPaths = ViewHierarchyUtility.GetViewImportsLocations(relativePath); foreach (var location in viewImportsPaths) { options.AddExpirationToken(_fileProvider.Watch(location)); } return options; }
public void SetOverwritesAndInvokesCallbacks() { var cache = CreateCache(); var value1 = new object(); string key = "myKey"; var callback1Invoked = new ManualResetEvent(false); var callback2Invoked = new ManualResetEvent(false); var options1 = new MemoryCacheEntryOptions(); options1.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration() { EvictionCallback = (subkey, subValue, reason, state) => { Assert.Equal(key, subkey); Assert.Same(subValue, value1); Assert.Equal(EvictionReason.Replaced, reason); var localCallbackInvoked = (ManualResetEvent)state; localCallbackInvoked.Set(); }, State = callback1Invoked }); var result = cache.Set(key, value1, options1); Assert.Same(value1, result); var value2 = new object(); var options2 = new MemoryCacheEntryOptions(); options2.PostEvictionCallbacks.Add(new PostEvictionCallbackRegistration() { EvictionCallback = (subkey, subValue, reason, state) => { // Shouldn't be invoked. var localCallbackInvoked = (ManualResetEvent)state; localCallbackInvoked.Set(); }, State = callback2Invoked }); result = cache.Set(key, value2, options2); Assert.Same(value2, result); Assert.True(callback1Invoked.WaitOne(TimeSpan.FromSeconds(30)), "Callback1"); Assert.False(callback2Invoked.WaitOne(TimeSpan.FromSeconds(30)), "Callback2"); result = cache.Get(key); Assert.Same(value2, result); Assert.False(callback2Invoked.WaitOne(TimeSpan.FromSeconds(30)), "Callback2"); }
public Task<int> GetTypesHashAsync() { // The serial number is store in local cache in order to prevent // loading the record if it's not necessary int serial; if (!_memoryCache.TryGetValue(TypeHashCacheKey, out serial)) { var options = new MemoryCacheEntryOptions() .AddExpirationToken(_signal.GetToken(TypeHashCacheKey)); serial = GetContentDefinitionRecord().Serial; _memoryCache.Set(TypeHashCacheKey, serial, options); } return Task.FromResult(serial); }
private ViewLocationCacheResult OnCacheMiss( ViewLocationExpanderContext expanderContext, ViewLocationCacheKey cacheKey) { // Only use the area view location formats if we have an area token. IEnumerable<string> viewLocations = !string.IsNullOrEmpty(expanderContext.AreaName) ? _options.AreaViewLocationFormats : _options.ViewLocationFormats; for (var i = 0; i < _options.ViewLocationExpanders.Count; i++) { viewLocations = _options.ViewLocationExpanders[i].ExpandViewLocations(expanderContext, viewLocations); } ViewLocationCacheResult cacheResult = null; var searchedLocations = new List<string>(); var expirationTokens = new HashSet<IChangeToken>(); foreach (var location in viewLocations) { var path = string.Format( CultureInfo.InvariantCulture, location, expanderContext.ViewName, expanderContext.ControllerName, expanderContext.AreaName); cacheResult = CreateCacheResult(expirationTokens, path, expanderContext.IsMainPage); if (cacheResult != null) { break; } searchedLocations.Add(path); } // No views were found at the specified location. Create a not found result. if (cacheResult == null) { cacheResult = new ViewLocationCacheResult(searchedLocations); } var cacheEntryOptions = new MemoryCacheEntryOptions(); cacheEntryOptions.SetSlidingExpiration(_cacheExpirationDuration); foreach (var expirationToken in expirationTokens) { cacheEntryOptions.AddExpirationToken(expirationToken); } return ViewLookupCache.Set<ViewLocationCacheResult>(cacheKey, cacheResult, cacheEntryOptions); }
private ViewLocationCacheResult LocatePageFromPath(string executingFilePath, string pagePath, bool isMainPage) { var applicationRelativePath = GetAbsolutePath(executingFilePath, pagePath); var cacheKey = new ViewLocationCacheKey(applicationRelativePath, isMainPage); ViewLocationCacheResult cacheResult; if (!ViewLookupCache.TryGetValue(cacheKey, out cacheResult)) { var expirationTokens = new HashSet<IChangeToken>(); cacheResult = CreateCacheResult(expirationTokens, applicationRelativePath, isMainPage); var cacheEntryOptions = new MemoryCacheEntryOptions(); cacheEntryOptions.SetSlidingExpiration(_cacheExpirationDuration); foreach (var expirationToken in expirationTokens) { cacheEntryOptions.AddExpirationToken(expirationToken); } // No views were found at the specified location. Create a not found result. if (cacheResult == null) { cacheResult = new ViewLocationCacheResult(new[] { applicationRelativePath }); } cacheResult = ViewLookupCache.Set<ViewLocationCacheResult>( cacheKey, cacheResult, cacheEntryOptions); } return cacheResult; }
public static TItem Set <TItem>(this IMemoryCache cache, object key, TItem value, MemoryCacheEntryOptions options, CacheTags tags) { UpdateTagsDictionaryWithLock(key, tags); options.PostEvictionCallbacks.Add(PostEvictionCallbackRegistration); return(cache.Set(key, value, options)); }
public void Main() { _cacheEntryOptions = GetCacheEntryOptions(); IMemoryCache cache = new MemoryCache(new MemoryCacheOptions()); SetKey(cache, "0"); PriodicallyReadKey(cache, TimeSpan.FromSeconds(1)); PeriodciallyRemoveKey(cache, TimeSpan.FromSeconds(11)); PeriodciallySetKey(cache, TimeSpan.FromSeconds(13)); Console.ReadLine(); Console.WriteLine("Shutting down"); }