Description
Description
Found by @mconnew during a PR for another MemoryCache bug. (#51761) We are mishandling CacheItemPolicy.ChangeMonitors in the MemoryCache. The docs for that property says:
If you change the set of change monitors on a CacheItemPolicy object after the CacheItemPolicy object has been passed to an ObjectCache implementation, the changes have no effect.
This implies that the dependencies are expected to be copied when passed in. If a caller passes a CacheItemPolicy to MemoryCache.Set, and then modifies the CacheItemPolicy.ChangeMonitors collection afterwards, that change will be reflected in the collection stored here. It's also not thread safe. For example, CallNotifyOnChanged gets an iterator which will throw if the collection is modified while iterating.
This has been present in MemoryCache since its inception in NetFx. I have not seen any reports of failures while iterating over a monitor collection while it changes though, which indicates that very few if any people are actually doing this. While fixing this bug would be a behavior change - and MemoryCache here is meant to be a bridge package to allow moving to .Net Core piece by piece, and thus compat is a huge consideration - I think it is acceptable risk to consider doing this correctly and taking a shallow copy of this monitor collection instead of a reference.