C# 为什么MemoryCache抛出NullReferenceException

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

更新

请参阅下面的更新,此问题在您安装.Net 4.6时已修复


我想在
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)