/// <inheritdoc /> public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { var key = GenerateKey(context); string result; if (!MemoryCache.TryGetValue(key, out result)) { // Create an EntryLink and flow it so that it is accessible via the ambient EntryLinkHelpers.ContentLink // for user code. var entryLink = new EntryLink(); using (entryLink.FlowContext()) { result = await context.GetChildContentAsync(); } MemoryCache.Set(key, cacheSetContext => { UpdateCacheContext(cacheSetContext, entryLink); return(result); }); } // Clear the contents of the "cache" element since we don't want to render it. output.SuppressOutput(); output.Content = result; }
public void LinkContextsCanNest() { var cache = CreateCache(); var obj = new object(); string key = "myKey"; string key1 = "myKey1"; var link1 = new EntryLink(); var link2 = new EntryLink(); Assert.Null(EntryLinkHelpers.ContextLink); using (link1.FlowContext()) { Assert.StrictEqual(link1, EntryLinkHelpers.ContextLink); using (link2.FlowContext()) { Assert.StrictEqual(link2, EntryLinkHelpers.ContextLink); var trigger = new TestTrigger() { ActiveExpirationCallbacks = true }; cache.Set(key, context => { context.AddExpirationTrigger(trigger); return(obj); }); } Assert.StrictEqual(link1, EntryLinkHelpers.ContextLink); } Assert.Null(EntryLinkHelpers.ContextLink); Assert.Equal(0, link1.Triggers.Count()); Assert.Null(link1.AbsoluteExpiration); Assert.Equal(1, link2.Triggers.Count()); Assert.Null(link2.AbsoluteExpiration); cache.Set(key1, context => { context.AddEntryLink(link2); return(obj); }); }
public void GetWithImplicitLinkPopulatesTriggers() { var cache = CreateCache(); var obj = new object(); string key = "myKey"; string key1 = "myKey1"; var link = new EntryLink(); Assert.Null(EntryLinkHelpers.ContextLink); using (link.FlowContext()) { Assert.StrictEqual(link, EntryLinkHelpers.ContextLink); var trigger = new TestTrigger() { ActiveExpirationCallbacks = true }; cache.Set(key, context => { context.AddExpirationTrigger(trigger); return(obj); }); } Assert.Null(EntryLinkHelpers.ContextLink); Assert.Equal(1, link.Triggers.Count()); Assert.Null(link.AbsoluteExpiration); cache.Set(key1, context => { context.AddEntryLink(link); return(obj); }); }
public void NestedLinkContextsCanAggregate() { var clock = new TestClock(); var cache = CreateCache(clock); var obj = new object(); string key1 = "myKey1"; string key2 = "myKey2"; string key3 = "myKey3"; var link1 = new EntryLink(); var link2 = new EntryLink(); var trigger2 = new TestTrigger() { ActiveExpirationCallbacks = true }; var trigger3 = new TestTrigger() { ActiveExpirationCallbacks = true }; cache.GetOrSet(key1, context1 => { using (link1.FlowContext()) { cache.GetOrSet(key2, context2 => { context2.AddExpirationTrigger(trigger2); context2.SetAbsoluteExpiration(TimeSpan.FromSeconds(10)); using (link2.FlowContext()) { cache.GetOrSet(key3, context3 => { context3.AddExpirationTrigger(trigger3); context3.SetAbsoluteExpiration(TimeSpan.FromSeconds(15)); return(obj); }); } context2.AddEntryLink(link2); return(obj); }); } context1.AddEntryLink(link1); return(obj); }); Assert.Equal(2, link1.Triggers.Count()); Assert.NotNull(link1.AbsoluteExpiration); Assert.Equal(clock.UtcNow + TimeSpan.FromSeconds(10), link1.AbsoluteExpiration); Assert.Equal(1, link2.Triggers.Count()); Assert.NotNull(link2.AbsoluteExpiration); Assert.Equal(clock.UtcNow + TimeSpan.FromSeconds(15), link2.AbsoluteExpiration); cache.Set(key1, context => { context.AddEntryLink(link2); return(obj); }); }
public void Main() { IMemoryCache cache = new MemoryCache(new MemoryCacheOptions()); object result; string key = "Key"; object newObject = new object(); object state = new object(); // Basic CRUD operations: // Create / Overwrite result = cache.Set(key, newObject); result = cache.Set(key, context => new object()); result = cache.Set(key, state, context => new object()); // Retrieve, null if not found result = cache.Get(key); // Retrieve bool found = cache.TryGetValue(key, out result); // Delete cache.Remove(key); // Conditional operations: // Retrieve / Create when we want to lazily create the object. result = cache.GetOrSet(key, context => new object()); // Retrieve / Create when we want to lazily create the object. result = cache.GetOrSet(key, state, context => new object()); // Cache entry configuration: // Stays in the cache as long as possible result = cache.GetOrSet(key, state, context => { context.SetPriority(CachePreservationPriority.NeverRemove); return(new object()); }); // Automatically remove if not accessed in the given time result = cache.GetOrSet(key, state, context => { context.SetSlidingExpiration(TimeSpan.FromMinutes(5)); return(new object()); }); // Automatically remove at a certain time result = cache.GetOrSet(key, state, context => { context.SetAbsoluteExpiration(new DateTime(2014, 12, 31)); // or relative: // context.SetAbsoluteExpiration(TimeSpan.FromMinutes(5)); return(new object()); }); // Automatically remove if not accessed in the given time // Automatically remove at a certain time (if it lives that long) result = cache.GetOrSet(key, state, context => { context.SetSlidingExpiration(TimeSpan.FromMinutes(5)); context.SetAbsoluteExpiration(new DateTime(2014, 12, 31)); // or relative: // context.SetAbsoluteExpiration(TimeSpan.FromMinutes(5)); return(new object()); }); // Callback when evicted result = cache.GetOrSet(key, state, context => { context.RegisterPostEvictionCallback((echoKey, value, reason, substate) => Console.WriteLine(echoKey + ": '" + value + "' was evicted due to " + reason), state: null); return(new object()); }); // Remove on trigger var cts = new CancellationTokenSource(); result = cache.GetOrSet(key, state, context => { context.AddExpirationTrigger(new CancellationTokenTrigger(cts.Token)); return(new object()); }); result = cache.GetOrSet(key, context => { var link = new EntryLink(); var inner1 = cache.GetOrSet("subkey1", link, subContext => { return("SubValue1"); }); string inner2; using (link.FlowContext()) { inner2 = cache.GetOrSet("subkey2", subContext => { return("SubValue2"); }); } context.AddEntryLink(link); return(inner1 + inner2); }); }