-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Background and Motivation
MemoryCache
by default tracks linked cache entries to allow for propagating options.
In the following example, the expirationToken
added for child
is also applied to parent
:
using (var parent = cache.CreateEntry(key))
{
parent.SetValue(obj);
using (var child = cache.CreateEntry(key1))
{
child.SetValue(obj);
child.AddExpirationToken(expirationToken);
}
}
Tracking internally uses AsyncLocal<T>
, which is expensive and adds non-trivial overhead. The cost of using it has popped out in the performance reports that we have received from our customers (#45436).
Currently, this feature can not be disabled.
Proposed API
As suggested by @Tratcher in #45436 (comment), we can extend the existing MemoryCacheOptions
with a flag that disables this behaviour.
Naming is hard and the best idea I currently have is TrackLinkedCacheEntries
:
namespace Microsoft.Extensions.Caching.Memory
{
public class MemoryCacheOptions
{
+ public bool TrackLinkedCacheEntries { get ; init; } = true;
}
}
I am open to suggestions.
Usage Examples
var options = new MemoryCacheOptions
{
TrackLinkedCacheEntries = false
};
var cache = new MemoryCache(options);
Alternative Designs
As an alternative, we could add a new method to MemoryCache
that would allow for creating cache entries without tracking:
namespace Microsoft.Extensions.Caching.Memory
{
public class MemoryCache
{
public ICacheEntry CreateEntry(object key); // existing method
+ public ICacheEntry CreateUnlinkedEntry(object key);
}
But there is a lot of existing extension methods that allow for adding new cache entries to the cache and we would most probably need to add new overloads for them...
Risks
Introducing this API has no risks as long as we don't change the default settings (enabled by default).