Изменение частоты истечения срока действия элемента кэша ASP.NET? - PullRequest
12 голосов
/ 06 ноября 2008

Я заметил, что элементы кэша ASP.NET проверяются (и, возможно, удаляются) каждые 20 секунд (и, как ни странно, каждый раз при ЧЧ: ММ: 00, ЧЧ: ММ: 20 и ЧЧ: ММ: 40). Я потратил около 15 минут на поиски того, как изменить этот параметр без какого-либо успеха. Я также попытался установить следующее в web.config, но это не помогло:

<cache privateBytesPollTime="00:00:05" />

Я не пытаюсь сделать что-нибудь сумасшедшее, но было бы неплохо, если бы, скажем, 5 секунд вместо 20 или хотя бы 10 для моего приложения.

Ответы [ 4 ]

19 голосов
/ 07 ноября 2008

Возмущение с помощью Reflector показывает, что интервал жестко закодирован. Истечение срока действия обрабатывается внутренним классом CacheExpires, статический конструктор которого содержит

_tsPerBucket = new TimeSpan(0, 0, 20);

_tsPerBucket равно readonly, поэтому не может быть никакого параметра конфигурации, который изменяет его позже.

Таймер, который будет запускать проверку для просроченных элементов, затем устанавливается в CacheExpires.EnableExpirationTimer() ...

DateTime utcNow = DateTime.UtcNow;
TimeSpan span = _tsPerBucket - new TimeSpan(utcNow.Ticks % _tsPerBucket.Ticks);
this._timer = new Timer(new TimerCallback(this.TimerCallback), null,
    span.Ticks / 0x2710L, _tsPerBucket.Ticks / 0x2710L);

Расчет span гарантирует, что таймер срабатывает точно в: 00,: 20,: 40 секунд, хотя я не вижу причин для беспокойства. Метод, который вызывает таймер, - internal, поэтому я не думаю, что есть какой-либо способ настроить свой собственный таймер, чтобы вызывать его чаще (игнорируя отражение).

Однако, хорошая новость заключается в том, что у вас не должно быть причин беспокоиться об интервале. Cache.Get() проверяет, что срок действия элемента не истек, и, если он есть, немедленно удаляет элемент из кэша и возвращает null. Поэтому вы никогда не получите элемент с истекшим сроком действия из кэша, даже если элементы с истекшим сроком действия могут оставаться в кэше до 20 секунд.

2 голосов
/ 01 сентября 2011

Безумное, но рабочее решение (нужны все шаги):

// New value for cache expiration cycle
// System.Web.Caching.CacheExpires._tsPerBucket;
// Set 1 seconds instead of 20sec
const string assembly = "System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
var type = Type.GetType("System.Web.Caching.CacheExpires, " + assembly, true, true);
var field = type.GetField("_tsPerBucket", BindingFlags.Static | BindingFlags.NonPublic);
field.SetValue(null, TimeSpan.FromSeconds(1));

// Recreate cache
// HttpRuntime._theRuntime._cacheInternal = null;
// HttpRuntime._theRuntime._cachePublic = null;
type = typeof (HttpRuntime);
field = type.GetField("_theRuntime", BindingFlags.Static | BindingFlags.NonPublic);
var runtime = field.GetValue(null);
field = type.GetField("_cachePublic", BindingFlags.NonPublic | BindingFlags.Instance);
field.SetValue(runtime, null);
field = type.GetField("_cacheInternal", BindingFlags.NonPublic | BindingFlags.Instance);
field.SetValue(runtime, null);
2 голосов
/ 06 ноября 2008

Согласно документации , privateBytesPollTime предназначен для «использования памяти рабочего процесса», и по умолчанию он равен 1 секунде. Я не думаю, что это связано с удалением элементов кэша.

Я подтвердил ваши результаты с помощью обратного вызова удаления элемента - похоже, элементы удаляются в нижней части минуты: 20 и: 40 секунд. Это говорит о том, что элемент может оставаться в кэше до 20 секунд после установленного на них AbsoluteExpiration. Я не смог найти никакой документации о том, можно ли изменить 20-секундный интервал опроса.

0 голосов
/ 28 января 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...