C# 为什么MemoryCache抛出NullReferenceException
更新 请参阅下面的更新,此问题在您安装.Net 4.6时已修复C# 为什么MemoryCache抛出NullReferenceException,c#,.net,multithreading,caching,.net-4.5,C#,.net,Multithreading,Caching,.net 4.5,更新 请参阅下面的更新,此问题在您安装.Net 4.6时已修复 我想在CacheItemPolicy的UpdateCallback中实现一些东西 如果这样做并测试代码在同一缓存实例上运行多个线程(MemoryCache.Default),则调用cache.Set方法时会出现以下异常 System.Runtime.Caching.dll!System.Runtime.Caching.MemoryCacheEntry.RemoveDependent(System.Runtime.Caching.M
我想在
CacheItemPolicy
的UpdateCallback
中实现一些东西
如果这样做并测试代码在同一缓存实例上运行多个线程(MemoryCache.Default
),则调用cache.Set
方法时会出现以下异常
System.Runtime.Caching.dll!System.Runtime.Caching.MemoryCacheEntry.RemoveDependent(System.Runtime.Caching.MemoryCacheEntryChangeMonitor dependent = {unknown}) C#
System.Runtime.Caching.dll!System.Runtime.Caching.MemoryCacheEntryChangeMonitor.Dispose(bool disposing = {unknown}) C#
System.Runtime.Caching.dll!System.Runtime.Caching.ChangeMonitor.DisposeHelper() C#
System.Runtime.Caching.dll!System.Runtime.Caching.ChangeMonitor.Dispose() C#
System.Runtime.Caching.dll!System.Runtime.Caching.ChangeMonitor.InitializationComplete() C#
System.Runtime.Caching.dll!System.Runtime.Caching.MemoryCacheEntryChangeMonitor.InitDisposableMembers(System.Runtime.Caching.MemoryCache cache = {unknown}) C#
System.Runtime.Caching.dll!System.Runtime.Caching.MemoryCacheEntryChangeMonitor..ctor(System.Collections.ObjectModel.ReadOnlyCollection<string> keys = {unknown}, string regionName = {unknown}, System.Runtime.Caching.MemoryCache cache = {unknown}) C#
System.Runtime.Caching.dll!System.Runtime.Caching.MemoryCache.CreateCacheEntryChangeMonitor(System.Collections.Generic.IEnumerable<string> keys = {unknown}, string regionName = {unknown}) C#
System.Runtime.Caching.dll!System.Runtime.Caching.MemoryCache.Set(string key = {unknown}, object value = {unknown}, System.Collections.ObjectModel.Collection<System.Runtime.Caching.ChangeMonitor> changeMonitors = {unknown}, System.DateTimeOffset absoluteExpiration = {unknown}, System.TimeSpan slidingExpiration = {unknown}, System.Runtime.Caching.CacheEntryUpdateCallback onUpdateCallback = {unknown}) C#
System.Runtime.Caching.dll!System.Runtime.Caching.MemoryCache.Set(string key = {unknown}, object value = {unknown}, System.Runtime.Caching.CacheItemPolicy policy = {unknown}, string regionName = {unknown}) C#
如果运行该命令,您应该直接获取异常。如果注释掉UpdateCallback setter,则不应再出现异常。如果只运行一个线程(更改Enumerable.Repeat)
2015年5月更新:
如果您安装了.Net 4.6附带的VS 2015 RC,则问题似乎已得到解决。我无法真正验证.Net的哪个版本修复了该问题,因为现在它在项目使用的所有版本中都能正常工作。无论我是否将其设置为.Net 4.5、4.5.1或4.5.2,该错误都不再可复制。微软似乎已经修复了此问题,至少在.Net 4.5.2中是这样。浏览显示,现在他们用来存储内部数据的字典的访问权限被锁定:
我通过NullReferenceException找到了此线程
内存缓存。
我的问题是在尝试向缓存添加内容时接收NullReferenceException
NullReferenceException
at System.Runtime.Caching.MemoryCacheStore.UpdateExpAndUsage(MemoryCacheEntry entry, Boolean updatePerfCounters)
at System.Runtime.Caching.MemoryCacheStore.AddOrGetExisting(MemoryCacheKey key, MemoryCacheEntry entry)
at System.Runtime.Caching.MemoryCache.AddOrGetExistingInternal(String key, Object value, CacheItemPolicy policy)
at System.Runtime.Caching.ObjectCache.Add(String key, Object value, CacheItemPolicy policy, String regionName)
MemoryCache是线程安全的。
我们在静态场中使用一个对象。
NRE的原因是另一个单独的线程试图通过调用cache.Dispose();cache=new MemoryCache()清除MemoryCache;
问题很容易在两个并行任务中重现:
一个任务将添加新对象
第二个将调用Dispose和new MemoryCache,0.5秒后,您将收到包含MemoryCache的NRE
.net 4.6.1
我刚刚替换了。处理并使用新的MemoryCache
foreach(var-kv-in-cache){cache.remove(kv.key)}
解决方案是不使用它^^^。对于滑动过期,我最后还使用绝对过期,并手动更新元素(过期超时)在get上。这样它工作得很好…请参阅'1.cs方法'GetCacheItemInternal',如果您可以复制它,您可能也想对这一个进行评级:对此有任何更新吗?根据@MichaC添加的链接,它已被解决…在某个地方,我在Win8上几秒钟内重复出现异常,但在Server 2012 R2上,10分钟后仍然会毫无异常。
internal void RemoveDependent(MemoryCacheEntryChangeMonitor dependent) {
lock (this) {
if (_fields._dependents != null) {
_fields._dependents.Remove(dependent);
}
}
}
NullReferenceException
at System.Runtime.Caching.MemoryCacheStore.UpdateExpAndUsage(MemoryCacheEntry entry, Boolean updatePerfCounters)
at System.Runtime.Caching.MemoryCacheStore.AddOrGetExisting(MemoryCacheKey key, MemoryCacheEntry entry)
at System.Runtime.Caching.MemoryCache.AddOrGetExistingInternal(String key, Object value, CacheItemPolicy policy)
at System.Runtime.Caching.ObjectCache.Add(String key, Object value, CacheItemPolicy policy, String regionName)