Ответ 1
Ура для Reflector!
Истекшие элементы кэша фактически удаляются (и вызываемые вызовы), если:
1) Что-то пытается получить доступ к элементу кэша.
2) Метод ExpiresBucket.FlushExpiredItems
запускается и переходит к элементу. Этот метод жестко закодирован для выполнения каждые 20 секунд (принятый ответ на вопрос StackOverflow Изменение частоты истечения срока действия кэша ASP.NET подтверждает мое чтение этого кода с помощью Reflector). Однако для этого требуется дополнительная квалификация (для которой читается).
Asp.Net поддерживает один кэш для каждого процессора на сервере (я не уверен, что это представляют собой логические или физические процессоры); каждый из них поддерживает экземпляр CacheExpires
, который имеет соответствующий Timer
, который вызывает его метод FlushExpiredItems
каждые двадцать секунд.
Этот метод выполняет поочередно по другому набору "ведра" данных об истечении срока хранения кеша (массив экземпляров ExpiresBucket
), вызывая каждый метод ведра FlushExpiredItems
.
Этот метод (ExpiresBucket.FlushExpiredItems
) сначала выполняет итерацию всех элементов кэша в ковше, и если элемент истек, отметки об этом истекли. Затем (я грубо упрощаю здесь) он выполняет итерацию элементов, которые он имеет истек, и удаляет их, выполняя CacheItemRemovedCallback
(на самом деле он вызывает CacheSingle.Remove
, который вызывает CacheInternal.DoRemove
, затем CacheSingle.UpdateCache
, затем CacheEntry.Close
, который фактически вызывает обратный вызов).
Все это происходит последовательно, поэтому есть шанс, что что-то может заблокировать весь процесс и удержать вещи (и вывести истечение срока действия кэша с указанного времени истечения срока действия).
Однако при этом временном разрешении с минимальным интервалом истечения 20 секунд единственной частью процесса, который может блокироваться в течение значительного периода времени, является выполнение CacheItemRemovedCallbacks
. Любой из них может, предположительно, блокировать заданный поток Timer
FlushExpiredItems
неопределенно. (Хотя двадцать секунд спустя, Timer
будет порождать другой поток FlushExpiredItems
.)
Подводя итог, Asp.Net не гарантирует, что он выполнит обратные вызовы в указанное время, но он будет делать это при некоторых условиях. Пока интервалы истечения более чем на двадцать секунд друг от друга, и пока кеш не должен выполнять трудоемкий CacheItemRemovedCallbacks
(глобально - любые обратные вызовы могут помешать любым другим), он может выполнять обратные вызовы график. Это будет достаточно хорошо для некоторых приложений, но не подходит для других.