Reputation: 313
I have a builder class that creates an instance implementing IDisposable. Whenever the item to build is already in the cache, the builder will return that instance instead. My question is, will the cache call the Dispose() method on the IDisposable items it contains when they are evicted or do I have to explicitly code that behavior on the callback CacheItemPolicy.RemovedCallback?
Upvotes: 10
Views: 3989
Reputation: 20668
UPDATE: Do not use the code below for certificates and similar objects. Another thread may still be using this instance when it is disposed. See this question and answer for solution if that is the case.
To add to the other answers, if you use GetOrCreateAsync
, use the ICacheEntry
parameter to manually call Dispose
. For example, I need to dispose X509Certificate2
for validating JWTs once my cache expires:
await cache.GetOrCreateAsync("IdTokenCerts", async entry =>
{
entry.AbsoluteExpirationRelativeToNow = JwtCertsCacheLifetime;
entry.RegisterPostEvictionCallback((_, value, _, _) =>
{
if (value is X509SecurityKey key)
{
key.Certificate.Dispose();
}
});
// ...
}
Upvotes: 0
Reputation: 173
I want to add to the accepted answer that you can let items be disposed on eviction if you want. Just call the Dispose()
method in the RemovedCallback
.
public class TestClass : IDisposable
{
public void Dispose()
{
Console.WriteLine("disposed");
}
}
MemoryCache _MemoryCache = new MemoryCache("TEST");
void Test()
{
_MemoryCache.Add("key",
new TestClass(),
new CacheItemPolicy()
{
AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(10),
RemovedCallback = (x) => { ((TestClass)x.CacheItem.Value).Dispose(); }
});
}
Upvotes: 2
Reputation: 35353
No Dispose
is not called. It is easy to test.
public class TestClass : IDisposable
{
public void Dispose()
{
Console.WriteLine("disposed");
}
}
MemoryCache _MemoryCache = new MemoryCache("TEST");
void Test()
{
_MemoryCache.Add("key",
new TestClass(),
new CacheItemPolicy()
{
AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(10),
RemovedCallback = (_) => { Console.WriteLine("removed"); }
});
}
Upvotes: 11