Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
The showcase for possible memory leaks if using a shared CancellationTokenSource for cached items
class Program
{
static void Main()
{
//global token source that being used for clear entire cached elements
var globalTokenSource = new CancellationTokenSource();
Action doWork = () =>
{
for (int i = 0; i < 100; i++)
{
var elementTokenSource = new CancellationTokenSource();
var options = new MemoryCacheEntryOptions();
var compositionToken = new CompositeChangeToken(new[] {
new CancellationChangeToken(elementTokenSource.Token),
new CancellationChangeToken(globalTokenSource.Token) });
options.AddExpirationToken(compositionToken);
//Intentionally set a small lifetime for cached data
options.SetAbsoluteExpiration(TimeSpan.FromTicks(1));
_memoryCache.Set(i.ToString(), "some cached data", options);
}
Thread.Sleep(1000);
//Enforce clean all data from cache
_memoryCache.Compact(1.0);
};
// Add some data into cache with shared Cancellation token
doWork();
Thread.Sleep(1000);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.WaitForFullGCComplete();
//Got memory leak with stale Cancellation token registers for all cached items until we not call globalTokenSource.Dispose()
}
}
@tatarincev
Copy link
Author

tatarincev commented Mar 1, 2021

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment