System.Runtime.Caching «забывает» о кэшировании при подключенном отладчике - PullRequest
1 голос
/ 12 сентября 2011

У меня есть набор компонентов приложения, которые требуют сохранения большой коллекции бизнес-объектов для достижения разумной производительности.По сути, это данные, которые считываются из базы данных и гидратируются в объекты для последующего повторного использования.

Эта коллекция объектов изначально была реализована в .net 3.5, поэтому для достижения этой устойчивости при загрузке во время выполнения ASP.Netиспользовался HttpRuntime.Cache, и если он был загружен клиентом win form, использовался блок кэширования корпоративной библиотеки.

Теперь с .net 4.0 для этих запросов доступно System.Runtime.Caching.Следующий шаблон был реализован для получения кэшированных элементов.

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 : Как это часто бывает здесь, через некоторое время после публикации вопроса я получилнемного больше деталей об ошибках из окна вывода отладчика.Эта ошибка привела меня к этой статье MS Connect.Оказывается, что при использовании удаленного взаимодействия (я) для вызова приложения, размещенного на ASP.NET, MemoryCache.Default, похоже, связывает свои вспомогательные таймеры (очистка кэша и т. Д.) С контекстом потока.Когда контекст потока больше недоступен, обратные вызовы не выполняются, и MemoryCache.Default перестает работать для всех других попыток.

Добавление ExecutionContext.SuppressFlow () (как видно из переработанного примера ниже)Остановите это вложение.

     Using ExecutionContext.SuppressFlow()

            _cache = MemoryCache.Default

     End Using

Я вставил это вчера, и с тех пор это было замечательно.

1 Ответ

0 голосов
/ 13 сентября 2011

не уверен, но я вижу, как вы используете кеш, немного отличается от примера в 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

вы также говорите, что эта проблема возникает, когда вы размещаете свои компоненты в приложении ASP.NET, в ASP.NET я лично использовал бы HttpContext.Current.Cache, возможно, что используемый вами MemoryCache уже делает это, не уверен потому что я никогда не использовал его раньше, поэтому не могу сказать, но как это будет работать, если вы измените Add с Set и будете использовать HttpContext? Просто проверьте HpptContext.Current, потому что он будет нулевым, если не работает в приложении ASP.NET.

Еще один момент, на который вы могли бы обратить внимание: когда вы присоединяете отладчик, действительно ли вы выполняете метод Cache.Add / Set?

...