HttpRuntime Close не удаляет элементы из кеша, как было объявлено

Asked
Viewd5090

1

Я создал свой собственный диспетчер кеша для разрабатываемого мной веб-сайта и искал лучший способ очистить кеш при определенных обстоятельствах.

Я нашел много статей, в которых говорится, что правильный способ очистки кеша - это вызвать HttpRuntime.Close ()

Однако в моей настройке модульных тестов я вызываю инкапсулированную функцию HttpRuntime.Close (), и кеш НЕ очищается.

Я ожидал, что он выполнит что-то подобное

 foreach (DictionaryEntry cacheItem in HttpRuntime.Cache)
{
    HttpRuntime.Cache.Remove(cacheItem.Key.ToString());
}
 

Цикл foreach отлично работает в моей инкапсулированной функции, но Close () никогда не работает правильно.

Я неправильно понимаю назначение HttpRuntime.Close () или здесь происходит что-то более зловещее?

3 ответов

9

Не используйте Close, он делает больше, чем говорится в документации. И в документации также сказано не использовать его при обработке обычных запросов ...

Это отраженный источник Close ():

 [SecurityPermission(SecurityAction.Demand, Unrestricted=true)]
public static void Close() {
    if (_theRuntime.InitiateShutdownOnce()) {
        SetShutdownReason(ApplicationShutdownReason.HttpRuntimeClose, "HttpRuntime.Close is called");
        if (HostingEnvironment.IsHosted) {
            HostingEnvironment.InitiateShutdown();
        } else {
            _theRuntime.Dispose();
        }
    }
}
 

Кроме того, вы не можете перебирать коллекцию и одновременно удалять из нее элементы, так как это делает перечисление недействительным.

Итак, попробуйте вместо этого, что не меняет того, что он зацикливает:

 List<string> toRemove = new List<string>();
foreach (DictionaryEntry cacheItem in HttpRuntime.Cache) {
    toRemove.Add(cacheItem.Key.ToString());
}
foreach (string key in toRemove) {
    HttpRuntime.Cache.Remove(key);
}
 

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

  • Ой, хорошо, спасибо за внимание. Что вы имеете в виду под зависимостями кеша?

    Joseph16 апреля 2009, 20:42
  • Когда записи добавляются в кеш, вы можете указать им зависимости, такие как тайм-аут, файл, другая кешированная запись и т. д., которые очистят элемент кеша, если эта зависимость сработает. См. Также http://msdn.microsoft.com/en-us/library/system.web.caching.cachedependency.aspx

    Lucero16 апреля 2009, 20:47
  • Это не совсем мой вопрос. Я имею в виду, что если у меня есть 4 элемента в кэше, и я перебираю их так, как я описал, в кэше остается 0 элементов. Однако, когда я использую Close (), 4 элемента все еще там.

    Joseph16 апреля 2009, 20:38
  • Это потому, что в документах говорится о том, что не является полной правдой. Close () не предназначен для очистки кеша.

    Lucero16 апреля 2009, 20:42
  • На самом деле я уже протестировал код, который задал в своем вопросе, и он работает нормально. Я понимаю проблему с перечислением, но по какой-то причине у кеша нет проблем с удалением элемента при просмотре списка.

    Joseph16 апреля 2009, 20:37
4

Я понимаю проблему с перечислением, но по какой-то причине у кэша, похоже, нет проблем с удалением элемента при просмотре списка.

Если вы углубитесь в детальную реализацию, вы обнаружите, что Enumerator создается CacheSingle.CreateEnumerator, а новый экземпляр Hashtable создается для перечисления.

Вот почему вы можете выполнять удаление в цикле foreach.