In a sane world, I would have expected the UpdateCallBack
property to increment my collection of arguments. But it doesn't: in the final line of this test, the updateArguments
collection is expected to be 3 (twice for each Set
call and once for the Remove
call), but it is empty.
The test is rough and ready, but it should be enough to illustrate that something odd is happening.
Or that I am missing something obvious.
EDIT: This is getting stranger. Based on the question MemoryCache UpdateCallback not working, which says that Thread.Sleep
blocks the MemoryCache.Default
object, I changed the original Thread.Sleep(5000)
call to Task.Factory.StartNew(() => Thread.Sleep(10000)).Wait();
. Then, if I comment out the call to MemoryCache.Default.Remove()
, the updateArguments
collection does indeed get incremented, but only once, and that is when the "PersonKey"
cached item expires. The two Set()
and one Remove()
calls are ignored completely. I'm having a "What the heck" moment.
[Test]
public void TheMemoryCacheMaintainsAMemberAndInvokesTheUpdateCallback()
{
var person = new Person { GivenName = "Rob", LastName = "Lyndon"};
var givenName = person.GivenName;
var lastName = person.LastName;
var updateArguments = new List<CacheEntryUpdateArguments>();
MemoryCache.Default.Set("PersonKey", person, CreateNewPolicy(updateArguments));
var cachedItem = MemoryCache.Default.Get("PersonKey") as Person;
Assert.IsNotNull(cachedItem);
Assert.That(cachedItem.GivenName, Is.EqualTo(givenName));
Assert.That(cachedItem.LastName, Is.EqualTo(lastName));
person.LastName = "Lyndon - Updated";
MemoryCache.Default.Set("PersonKey", member, CreateNewPolicy(updateArguments));
cachedItem = MemoryCache.Default.Get("PersonKey") as Person;
Assert.IsNotNull(cachedItem);
Assert.That(cachedItem.GivenName, Is.EqualTo(givenName));
Assert.That(cachedItem.LastName, Is.EqualTo(lastName + " - Updated"));
Task.Factory.StartNew(() => Thread.Sleep(10000)).Wait();
Thread.Sleep(5000);
Assert.That(updateArguments.Count, Is.EqualTo(3));
}
private static CacheItemPolicy CreateNewPolicy(ICollection<CacheEntryUpdateArguments> updateArguments)
{
return new CacheItemPolicy
{
AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(1),
UpdateCallback = args => updateArguments.Add(args)
};
}