我有一个构建器类,它创建一个实现 IDisposable 的实例。每当要构建的项目已在缓存中时,构建器将返回该实例。我的问题是,缓存是否会在其包含的 IDisposable 项被逐出时调用 Dispose() 方法,还是我必须在回调 CacheItemPolicy.RemovedCallback 上显式编码该行为?
不
Dispose
未被调用。很容易测试。
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"); }
});
}
我想在已接受的答案中添加一点,如果您愿意,您可以在驱逐时处置物品。只需调用
Dispose()
中的 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(); }
});
}
要添加到其他答案,如果您使用
GetOrCreateAsync
,请使用 ICacheEntry
参数手动调用 Dispose
。例如,一旦我的缓存过期,我需要处理 X509Certificate2
来验证 JWT:
await cache.GetOrCreateAsync("IdTokenCerts", async entry =>
{
entry.AbsoluteExpirationRelativeToNow = JwtCertsCacheLifetime;
entry.RegisterPostEvictionCallback((_, value, _, _) =>
{
if (value is X509SecurityKey key)
{
key.Certificate.Dispose();
}
});
// ...
}