System.Web.HttpContext.Current обнуляется после проверки кэша
Сегодня я столкнулся со странной проблемой, которая не имела для меня никакого смысла. Вот резюме:
Внутри метода я проверяю наличие кэшированного элемента, как показано ниже:
private async Task<RatesStatus> getRatesStatusAsync() {
//...
if (_currentHttpContext != null) {
//Here, I am checking for a Cached item
var cachedRatesStatusObj = HttpContext.Current.Cache[Constants.RATESSTATUS_CACHE_KEY_NAME];
if (cachedRatesStatusObj != null)
return (RatesStatus)cachedRatesStatusObj;
}
//...
cacheRatesStatusObject(ratesStatus);
//...
}
Здесь HttpContext.Current
не является нулевым, как ожидалось внутри приложения ASP.NET. Затем внутри cacheRatesStatusObject
метод, я проверяю, если HttpContext.Current
Нуль или нет, как показано ниже:
private void cacheRatesStatusObject(RatesStatus ratesStatus) {
//...
//Seeing if HttpContext.Current is null or not first.
//and it is null here...
if (HttpContext.Current == null)
return;
//...
}
И это ноль там. Понятия не имею, что здесь происходит. Какие-нибудь мысли?
3 ответа
Когда вы используете async/await, поток, обрабатывающий запрос, помечает запрос как незавершенный и затем возвращается к ASP.NET thread pool
, Когда ожидаемое завершается позже, другой поток назначается для выполнения остальной части метода, однако HttpContext не переносится между потоками, поэтому при вызове метода await вы получаете нулевую ссылку.
Вы можете передать ссылку на HttpContext методу await, примерно так:
await cacheRatesStatusObject(HttpContext.Current, ratesStatus);
Однако вы должны быть очень осторожны, работая с условиями параллелизма и гонки, например, если поток await блокирует ресурс, а другой поток запроса пытается его использовать, тогда ваш пул потоков становится бумом. Большинство людей решают эту проблему, создавая новые объекты и передавая их в параматеризованные потоки вместо передачи ссылки на HttpContext между потоками.
Передача инстанса отстой.
Вместо этого используйте классы.NET 4 MemoryCache.
Это не обнуляет себя.
HttpContext
хранится только в "статическом потоке".
Как подсказывает другой ответ, просто пропустите экземпляр.