In my application, I have a Dictionary<int, WeakReference<Foo>>
to cache Foo
s read from a file, where the key is the index in the file. Since the Foo
s 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?
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.