MemoryCache – Acceptably unpredictable

If you’re not familiar with System.Runtime.Caching.MemoryCache, chances are that the following code does three things you wouldn’t expect…

https://gist.github.com/alexdresko/bd08881515a0a7a5ad0f

Take a look at the call to AddOrGetExisting. Here’s the method signature if it helps..

https://gist.github.com/alexdresko/774785378673cfa00643

Doesn’t look too suspicious, does it? If you’ve never seen MemoryCache.AddOrGetExisting, you might have made the following incorrect assumptions:

  1. The first time you call AddOrGetExisting, it should add the value, stringToCache in my example, to the cache and return that same value. In other words you might think that yeResult, in my example, would be “tada!!!”, right? Wrong. It’s null the first time you call it.

    Per the documentation:

    Return Value
    Type: System.Object
    If a cache entry with the same key exists, the existing cache entry; otherwise, null.

    Odd at first, but it’s not hard to get around. I’ll try to post another article soon explaining why this happens.

  2. You might think that the parameters we passed to AddOrGetExisting would cause the cache to expire in 10 seconds, right? Wrong. It’s 20 seconds. At least. Per this valuable answer, the internal TimeSpan that periodically checks the cache is configured for 20 seconds. So you can’t expect to set the timeout for anything less than 20 seconds by default.
  3. And I say “at least” above because, in my experience, even if you set the expiration date 20 seconds from now, it might expire in 20 seconds… or it might be 22.. or 27.. or 30… or who knows! It’s unpredictable. I imagine it’s because MemoryCache is doing fancy things behind the scenes. Maybe one day I’ll look into it further.

For my purposes, MemoryCache.AddOrGetExisting works perfectly fine! I just wish someone had told me these things before I started using it.