System.Runtime.Caching "забывает" о кэшировании при подключенном отладчике
У меня есть набор компонентов приложения, которые требуют сохранения большой коллекции бизнес-объектов для достижения разумной производительности. По сути, это данные, которые считываются из базы данных и объединяются в объекты для последующего повторного использования.
Эта коллекция объектов изначально была реализована в.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. Оказывается, что при использовании удаленного взаимодействия (I) для вызова приложения, размещенного на ASP.NET, MemoryCache.Default, похоже, связывает свои вспомогательные таймеры (очистка кэша и т. Д.) С контекстом потока. Когда контекст потока больше недоступен, обратные вызовы не выполняются, и MemoryCache.Default перестает работать для всех других попыток.
Добавление ExecutionContext.SuppressFlow() (как видно из переработанного примера ниже), кажется, останавливает это вложение.
Using ExecutionContext.SuppressFlow()
_cache = MemoryCache.Default
End Using
Я положил это во вчерашний день, и это было персиковым с тех пор.
1 ответ
Не уверен, но я вижу, как вы используете кеш, немного отличается от примера в 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?