附加调试器时System.Runtime.Caching“忘记”缓存

时间:2011-09-12 18:55:09

标签: .net caching .net-4.0 objectcache

我有一套应用程序组件,需要持久化大型业务对象集合才能实现合理的性能。这本质上是从数据库中读取并水化为对象以供以后重用的数据。

这个对象集最初是在.net 3.5中实现的,所以为了在ASP.Net运行时加载时实现这种持久性,使用了HttpRuntime.Cache,如果它是由win forms客户端加载的,那么企业库缓存使用了块。

现在,使用.net 4.0,System.Runtime.Caching可用于这些请求。为缓存项get实现了以下模式。

Public Function GetCachedObject(cacheKey as String) as Object

    Dim _returnValue as Object 

    SyncLock m_lockObject //some private lock object

      Dim _cache as ObjectCache = MemoryCache.Default

      //This is never found when debugging
      If _cache.Item(cacheKey) IsNot Nothing Then 
        _returnValue = _cache.Item
      Else
          Dim _policy As New System.Runtime.Caching.CacheItemPolicy()
          _policy.AbsoluteExpiration = DateTime.Now.AddHours(12)

          Dim _obj as Object = MethodToGetAndHydrateObject()
          _cache.Add(New CacheItem(cacheKey, _obj), _policy)
          _returnValue = _obj 
      End If

    End SyncLock

    Return _returnValue

End Function

这似乎有用,但只要没有附加调试器(vs2010)

连接调试器后,上面提到的缓存存在检查总是不返回任何内容。

这些是如何使用MSDN缓存的大量例子。是否有我遗漏的东西,或者这是真正意想不到的行为?

更新:我发现组件在ASP.net中托管时会发生这种情况。我可以构建DLL,将它们复制到站点,运行一些步骤并执行它。一旦我附加调试器并再次执行步骤,它就会显示此行为。

更新2 :正如我经常发生的那样,在我发布问题后不久,我从调试器输出窗口得到了更多的错误细节。此错误详细信息让我看到this MS Connect文章。事实证明,当使用远程处理(我)调用ASP.NET托管应用程序时,MemoryCache.Default似乎将其清除计时器(缓存清理等)与线程上下文联系起来。当线程上下文不再可用时,回调失败并且MemoryCache.Default似乎停止所有其他尝试。

添加ExecutionContext.SuppressFlow()(如下面的重做示例所示)似乎会停止此附件。

     Using ExecutionContext.SuppressFlow()

            _cache = MemoryCache.Default

     End Using

我把这个放在昨天,从那以后就变得很好了。

1 个答案:

答案 0 :(得分:0)

不确定,但我看到你使用缓存的方式与MSDN中的示例略有不同,你调用的是add方法而不是Set。

这里是我发现的例子:

Private Sub btnGet_Click(ByVal sender As Object, ByVal e As EventArgs) 
    Dim cache As ObjectCache = MemoryCache.[Default] 
    Dim fileContents As String = TryCast(cache("filecontents"), String) 

    If fileContents Is Nothing Then 
        Dim policy As New CacheItemPolicy() 
        Dim filePaths As New List(Of String)() 
        filePaths.Add("c:\cache\example.txt") 

        policy.ChangeMonitors.Add(New HostFileChangeMonitor(filePaths)) 

        ' Fetch the file contents.
        fileContents = File.ReadAllText("c:\cache\example.txt") 

        cache.[Set]("filecontents", fileContents, policy) 
    End If 

    Label1.Text = fileContents
End Sub

在此处找到:MemoryCache Class

你还说当你在ASP.NET应用程序中托管你的组件时会发生这个问题,在ASP.NET中我个人会使用HttpContext.Current.Cache你可能正在使用的这个MemoryCache已经这样做了,不确定,因为我之前从未使用它,所以无法分辨,但如果你改变Add with Set并使用HttpContext的那个怎么样呢?只需检查HpptContext.Current,因为如果没有在ASP.NET应用程序中运行它将为null。

您可以注意的另一点是,当您附加调试器时,您是否真的执行了Cache.Add / Set方法?