Почему не System.Web.Caching.Cache onUpdateCallback
уважать absolutionExpiration
время?
Я экспериментирую с созданием стратегии кэша, которая автоматически обновится после определенного интервала. Тем не менее, я хочу, чтобы кеш обновлялся в фоновом потоке вместо выселения, а затем ожидал, что новый пользовательский запрос заставит обновление кэша. Я решил использовать onUpdateCallback
для повторного onUpdateCallback
кеша, как только будет достигнуто абсолютное истечение.
Я создал образец контроллера, чтобы проиллюстрировать это:
public class ExampleController : Controller
{
private const string CacheKey = "Test";
//Simple function to get current time
private readonly Func<string> GetTime =
() => DateTime.Now.ToString("HH:mm:ss fff");
//Cache for 5 seconds
private readonly TimeSpan _cacheDuration = new TimeSpan(0, 0, 5);
private static bool _cacheWarmed = false;
private void WarmCache()
{
if (_cacheWarmed)
return;
_cacheWarmed = true;
//Cache current time
HttpContext.Cache
.Insert(
key: CacheKey,
value: GetTime(),
dependencies: null,
absoluteExpiration: DateTime.Now.Add(_cacheDuration),
slidingExpiration: Cache.NoSlidingExpiration,
//On cache eviction - cache current time (ie eviction time)
onUpdateCallback:
(string s,
CacheItemUpdateReason reason,
out object cachedItem,
out CacheDependency dependency,
out DateTime expiration,
out TimeSpan slidingExpiration) =>
{
expiration = DateTime.Now.Add(_cacheDuration);
cachedItem = GetTime();
dependency = null;
slidingExpiration = Cache.NoSlidingExpiration;
});
}
public ActionResult GetCachedTime()
{
WarmCache();
return new ContentResult
{
Content = (string)HttpContext.Cache.Get(CacheKey)
};
}
}
И простой Html с некоторым javascript для вызова метода снова и снова и вывода результата:
<script type="text/javascript">
$(document).ready(function() {
var myFunc = function()
{
var startTime = new Date().getTime();
$.ajax({
url: "/example/GetCachedTime"
}).done(function(data) {
var currentTime = new Date();
var msg =
currentTime.toLocaleTimeString() +
": [" +
data +
"] - Executed in " +
(currentTime.getTime() - startTime) +
" ms <br/>";
$("#container").append(msg);
console.log(msg);
});
};
var intervalHandle = setInterval(myFunc, 2000);
myFunc();
});
</script>
Усеченный для краткости:
3:45:52 PM: [15:45:40 387] - Executed in 30 ms
3:45:55 PM: [15:45:40 387] - Executed in 4 ms
3:45:57 PM: [15:45:40 387] - Executed in 4 ms
3:45:59 PM: [15:45:40 387] - Executed in 4 ms
3:46:01 PM: [15:46:00 399] - Executed in 4 ms
3:46:03 PM: [15:46:00 399] - Executed in 4 ms
(duplicates removed - :04 - :18)
3:46:19 PM: [15:46:00 399] - Executed in 3 ms
3:46:21 PM: [15:46:20 406] - Executed in 4 ms
3:46:23 PM: [15:46:20 406] - Executed in 3 ms
(duplicates removed - :24 - :38)
3:46:39 PM: [15:46:20 406] - Executed in 3 ms
3:46:41 PM: [15:46:40 418] - Executed in 3 ms
3:46:43 PM: [15:46:40 418] - Executed in 3 ms
(duplicates removed - :44 - :58)
3:46:59 PM: [15:46:40 418] - Executed in 3 ms
3:47:01 PM: [15:47:00 419] - Executed in 3 ms
3:47:03 PM: [15:47:00 419] - Executed in 3 ms
Метод кэшируется в течение 20
секунд, хотя я установил тайм-аут на 5
!
Я экспериментирую с изменением продолжительности кеша:
_cacheDuration = new TimeSpan(0, 0, 1)
- Без изменений_cacheDuration = new TimeSpan(0, 0, 10)
- Без изменений_cacheDuration = new TimeSpan(0, 0, 20)
- Без изменений_cacheDuration = new TimeSpan(0, 0, 25)
- кэшируется в течение 40 секундТак что происходит здесь? Почему кеш-память не соблюдается? Или я не правильно настроил кеш?
В кэше ASP.NET имеется внутренний таймер, который проверяет срок действия каждые 20 секунд. 5 секунд слишком мало времени, не изменяя период опроса кеша, который некоторые пользователи сделали.