0

Looking for a solution to a FileSystemWatcher issue I found a very interesting solution cited here FileSystemWatcher Changed event is raised twice from the original by Ben Hall

Now, my new problem is about a MemoryCache object with an expiration set by a CacheItemPolicy.

My final code is almost identical to the example above, besides the class that declares those objects. The confusing result is that the MemoryCache doesn't expire on the time I set with the property MemoryCache.AbsoluteExpiration or MemoryCache.SlidingExpiration, but it does so on a fixed 20 seconds boundary.

What I mean is that if I set something like

    private readonly MemoryCache _memCache = MemoryCache.Default;
    private CacheItemPolicy _cacheItemPolicy = new CacheItemPolicy();
    ...
    private void OnRemoveFromCache(CacheEntryRemovedArguments arguments)
    {
        if (arguments.RemovedReason != CacheEntryRemovedReason.Expired)
            return;
        
        var e = (FileSystemEventArgs)arguments.CacheItem.Value;
        
        //  Process e
        ...
    }

    public void Watcher_Changed(object sender, FileSystemEventArgs e)
    {
        _cacheItemPolicy = new()
        {
            RemovedCallback = OnRemoveFromCache,
            AbsoluteExpiration =
                DateTimeOffset.Now.AddMilliseconds(100.0)
        };
        _memCache.AddOrGetExisting(e.Name, e, _cacheItemPolicy);
    }

the callback OnRemoveFromCache is called only on the seconds :00, :20 or :40

That is if my event happens at 12:34:05.000 the callback happens at 12:34:20.000, or if the event is at 12:34:23.000 the callback runs at 12:34:40.000

What is the point I'm missing?

[EDIT] Oh well, as pointed out by @Alberto, here's Ben Hall dismantling the previous article by... the same Ben Hall! :D

And the same from my own little investigation: MemoryCache can only respond with a 20-seconds granularity...

Next question: is there an alternative with a similar pattern and a finer-grained timer or should I bake it myself? :O

lmattcris
  • 49
  • 3
  • Looks like the 20-seconds granularity is fixed... Shall I build a (simplified!) MemoryCache alike, with a more responsive timer, or is there a ready-to-use alternative? – lmattcris Sep 02 '22 at 13:51

1 Answers1

0

As pointed out in this blog post there are 2 ways expired items are evicted from the cache:

  • Every 20 seconds, on a Timer
  • Whenever an item is accessed if it is expired

Couldn't fine anything in the official documentation btw.

Alberto
  • 15,626
  • 9
  • 43
  • 56
  • That confirms my suspicions, as I delved into MemoryCache code... What I found is exactly some 20 seconds granularity. The funny part is that the article you mention is still from Ben Hall: then his own other example is wrong! You can't set a 1-second expiration and expect it to be respected! :D – lmattcris Sep 02 '22 at 13:48