public void CreateCacheEntryChangeMonitor () { var mc = new PokerMemoryCache ("MyCache"); AssertExtensions.Throws<NotSupportedException> (() => { mc.CreateCacheEntryChangeMonitor (new string [] { "key" }, "region"); }, "#A1-1"); AssertExtensions.Throws<ArgumentNullException> (() => { mc.CreateCacheEntryChangeMonitor (null); }, "#A1-2"); AssertExtensions.Throws<ArgumentException> (() => { mc.CreateCacheEntryChangeMonitor (new string [] {}); }, "#A1-3"); AssertExtensions.Throws<ArgumentException> (() => { mc.CreateCacheEntryChangeMonitor (new string [] { "key", null }); }, "#A1-4"); mc.Set ("key1", "value1", ObjectCache.InfiniteAbsoluteExpiration); mc.Set ("key2", "value2", ObjectCache.InfiniteAbsoluteExpiration); mc.Set ("key3", "value3", ObjectCache.InfiniteAbsoluteExpiration); CacheEntryChangeMonitor monitor = mc.CreateCacheEntryChangeMonitor (new string [] { "key1", "key2" }); Assert.IsNotNull (monitor, "#A2-1"); Assert.AreEqual ("System.Runtime.Caching.MemoryCacheEntryChangeMonitor", monitor.GetType ().ToString (), "#A2-2"); Assert.AreEqual (2, monitor.CacheKeys.Count, "#A2-3"); Assert.AreEqual ("key1", monitor.CacheKeys [0], "#A2-3-1"); Assert.AreEqual ("key2", monitor.CacheKeys [1], "#A2-3-2"); Assert.IsNull (monitor.RegionName, "#A2-4"); // Since this comparison can fail from time to time, leaving it commented out //Assert.AreEqual (DateTimeOffset.UtcNow.ToString (), monitor.LastModified.ToString (), "#A2-5"); Assert.IsFalse (monitor.HasChanged, "#A2-5"); // The actual unique id is constructed from key names followed by the hex value of ticks of their last modifed time Assert.IsFalse (String.IsNullOrEmpty (monitor.UniqueId), "#A2-6"); // There seems to be a bug in .NET 4.0 regarding the code below. MSDN says that non-existing keys will cause the // returned monitor instance to be marked as changed, but instead this exception is thrown: // // MonoTests.System.Runtime.Caching.MemoryCacheTest.CreateCacheEntryChangeMonitor: // System.ArgumentOutOfRangeException : The UTC time represented when the offset is applied must be between year 0 and 10,000. // Parameter name: offset // // at System.DateTimeOffset.ValidateDate(DateTime dateTime, TimeSpan offset) // at System.DateTimeOffset..ctor(DateTime dateTime) // at System.Runtime.Caching.MemoryCacheEntryChangeMonitor.InitDisposableMembers(MemoryCache cache) // at System.Runtime.Caching.MemoryCache.CreateCacheEntryChangeMonitor(IEnumerable`1 keys, String regionName) // at MonoTests.Common.PokerMemoryCache.CreateCacheEntryChangeMonitor(IEnumerable`1 keys, String regionName) in C:\Users\grendel\documents\visual studio 2010\Projects\System.Runtime.Caching.Test\System.Runtime.Caching.Test\Common\PokerMemoryCache.cs:line 113 // at MonoTests.System.Runtime.Caching.MemoryCacheTest.CreateCacheEntryChangeMonitor() in C:\Users\grendel\documents\visual studio 2010\Projects\System.Runtime.Caching.Test\System.Runtime.Caching.Test\System.Runtime.Caching\MemoryCacheTest.cs:line 275 // // It's probably caused by the code passing a DateTime.MinValue to DateTimeOffset constructor for non-existing entries. // Until this (apparent) bug is fixed, Mono is going to implement the buggy behavior. // #if true AssertExtensions.Throws<ArgumentOutOfRangeException> (() => { monitor = mc.CreateCacheEntryChangeMonitor (new string [] { "key1", "doesnotexist" }); }, "#A3"); #else monitor = mc.CreateCacheEntryChangeMonitor (new string [] { "key1", "doesnotexist" }); Assert.IsNotNull (monitor, "#A3-1"); Assert.AreEqual ("System.Runtime.Caching.MemoryCacheEntryChangeMonitor", monitor.GetType ().ToString (), "#A3-2"); Assert.AreEqual (1, monitor.CacheKeys.Count, "#A3-3"); Assert.AreEqual ("key1", monitor.CacheKeys [0], "#A3-3-1"); Assert.IsNull (monitor.RegionName, "#A3-4"); Assert.IsTrue (monitor.HasChanged, "#A3-5"); #endif }