Search code examples
c#memorycache

MemoryCache do not update item in Updatecallback


I write the following code (in linqpad) to demonstrate my issue:

void Main()
{
    var waitEvent = new AutoResetEvent(false);
    MemoryCache.Default.Set(
        "test", 
        "value", 
        new CacheItemPolicy
        {
            AbsoluteExpiration = DateTimeOffset.UtcNow.Add(TimeSpan.FromSeconds(5)),
            UpdateCallback = (CacheEntryUpdateArguments e) => {
                waitEvent.Set();
                e.Dump();
                e.UpdatedCacheItem = new CacheItem(e.Key, "value2");
            }
        });

    MemoryCache.Default.Get("test").Dump();
    waitEvent.WaitOne();
    waitEvent.WaitOne(TimeSpan.FromSeconds(10));


    MemoryCache.Default.Get("test").Dump();

}

// Define other methods and classes here

The result is as below:

enter image description here

Can anyone explain why I cannot get "value2" as the result?


Solution

  • You have to assign a new policy also when assigning a new item to UpdatedCacheItem. The docs are fairly wishy-washy (UpdatedCacheItem seems to say it's required, UpdatedCacheItemPolicy seems to imply it's optional1). However, the source makes it clear:

    // invoke update callback
    try {
        CacheEntryUpdateArguments args = new CacheEntryUpdateArguments(cache, reason, entry.Key, null);
        entry.CacheEntryUpdateCallback(args);
        Object expensiveObject = (args.UpdatedCacheItem != null) ? args.UpdatedCacheItem.Value : null;
        CacheItemPolicy policy = args.UpdatedCacheItemPolicy;
        // Dev10 861163 - Only update the "expensive" object if the user returns a new object,
        // a policy with update callback, and the change monitors haven't changed.  (Inserting
        // with change monitors that have already changed will cause recursion.)
        if (expensiveObject != null && IsPolicyValid(policy)) {
              cache.Set(entry.Key, expensiveObject, policy);
        }
        else {
              cache.Remove(entry.Key);
        }
    

    IsPolicyValid returns false if policy is null.


    1 Quotes:

    you must assign a CacheItem object to the UpdatedCacheItem property and assign a CacheItemPolicy object to the UpdatedCacheItemPolicy property

    versus:

    you can optionally assign a CacheItemPolicy object to the UpdatedCacheItemPolicy property