Example #1
0
        public async Task CacheExpirationTimeTest()
        {
            const int cacheSeconds = 2;

            var testObject = new TestObject()
            {
                Name = "My Test"
            };
            var weakReference = new TimedCacheWeakReference <TestObject>(testObject, TimeSpan.FromSeconds(cacheSeconds));

            Assert.IsTrue(weakReference.StrongReferenceAvailable, "No strong reference available");

            //Drop my strong refrence, and perform a GC
            testObject = null;
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

            //We are well within our cache time, so we should still have a reference
            Assert.IsTrue(weakReference.StrongReferenceAvailable, "Lost reference before cache timeout expired");

            //Now wait past our cache second time, then do a GC and verify we've lost the reference
            await Task.Delay(TimeSpan.FromSeconds(cacheSeconds + 1));

            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            Assert.IsFalse(weakReference.StrongReferenceAvailable, "Strong reference is still available after cache expiration");
        }
Example #2
0
        private static void RegisterExpiration(TimedCacheWeakReference <T> classToRegister, T target)
        {
            lock (cacheExpirationLock)
            {
                //Force set the target while we are within this class, in case it was cleared out in our expiration handler while we were waiting for the lock
                classToRegister.strongReference = target;

                var existing = registeredCacheExpirationItems.FirstOrDefault(item => item.TimedCacheWeakReference == classToRegister);
                if (target == null)
                {
                    //Strong reference has already been claimed, so remove this item from the collection
                    registeredCacheExpirationItems.Remove(existing);
                }
                else
                {
                    if (existing == null)
                    {
                        //Register a new item for expiration
                        registeredCacheExpirationItems.Add(new CacheExpirationRecord()
                        {
                            ExpirationTime          = DateTime.Now.Add(classToRegister.CacheDuration),
                            TimedCacheWeakReference = classToRegister
                        });
                    }
                    else
                    {
                        //Extend expiration lease
                        existing.ExpirationTime = DateTime.Now.Add(classToRegister.CacheDuration);
                    }

                    //Initialize our timer if it isn't already running
                    if (cacheExpirationTimer == null)
                    {
                        cacheExpirationTimer = new Timer(OnCacheExpirationTimer_Elapsed, null, cacheTimerInterval, cacheTimerInterval);
                    }
                }
            }
        }