Search code examples
.netcachinggarbage-collectionweak-referencesfinalizer

Cleaning up a cache of .net WeakReferences


In my application, I have a Dictionary<int, WeakReference<Foo>> to cache Foos read from a file, where the key is the index in the file. Since the Foos are mutable, a cache entry must remain alive as long as any reference to the Foo at that index (so that changes are visible to any holders as well as anyone reading fresh from the Foo source).

I would like to remove the Dictionary entry once the Foo is completely unreferenced. My initial idea had the finalizer of Foo remove itself from the cache, but this led to inconsistent internal state when a GC was triggered on cache insertion. I'm trying to take to heart the concept that finalizers cannot be used for managed memory, period. So is there any way to do this?


Solution

  • I ended up solving this with a project I'm calling BackgroundFinalizer (source on github). Essentially this allows you to define a "finalizer" that is not run during garbage collection and instead is run in the background. So in my particular case here, when the Foo is garbage collected a function which removes the entry from the cache is scheduled to run in a worker thread independent of the GC, so we avoid any cases of blocking in a finalizer or inconsistent internal state.