2012-05-11 4 views
5

Сегодня у меня возникла странная проблема, которая для меня не имела смысла. Вот краткое изложение: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; 

    //... 
} 

И это нуль там. Не знаю, что здесь происходит. Есть предположения?

+1

Я заметил, что ваш метод отмечен 'async'. Чтобы быть уверенным, где бы вы ни называли этот метод, вы «ожидаете» где-то перед тем, как «Ответ» будет отправлен обратно клиенту и закрыт, правильно? В противном случае это может быть просто условие гонки, когда «Ответ» возвращается и удаляется перед тем, как попасть в эту строку, но все еще доступен в строке выше. –

+0

@GuthMD Да, я использовал 'await' где-то внутри метода. Это должна быть проблема. – tugberk

ответ

4

Когда вы используете async/await, поток, обрабатывающий запрос, помечает запрос как неполный, а затем возвращается к ASP.NET thread pool. Когда ожидание завершается позже, другой поток назначается для запуска остальной части метода, однако HttpContext не переносится по потокам, поэтому вы получаете нулевую ссылку при вызове метода ожидания.

Вы можете передать ссылку в HttpContext методы ЖДЕТ, что-то вроде этого:

await cacheRatesStatusObject(HttpContext.Current, ratesStatus); 

Однако вы должны быть очень осторожны, имеет дело с параллелизмом и гоночными условиями, например, если Await нить блокирует ресурс и другой поток запросов пытается использовать его, тогда ваш пул потоков идет бум. Большинство людей разрешают это, создавая новые объекты и передавая их в параметризованные потоки вместо передачи ссылки HttpContext по потокам.

+0

Фактически 'HttpContext.Current' не является нулевым после ожидания. В методе async он равен нулю. См. Этот вопрос: http://aspnetwebstack.codeplex.com/discussions/359012 – Aliostad

0

Это не само по себе.

HttpContext хранится только в статическом виде.

Как следует из другого ответа, просто передайте экземпляр.

+0

Да, я просто понял это. Я получаю экземпляр его перед асинхронным вызовом: «var httpContext = HttpContext.Current;», а затем в этом процессе я работаю с этой локальной переменной. – tugberk

+0

Это не имеет большого смысла. Почему контекст потока не копируется ?? – Aliostad

+0

@Aliostad: Это как раз то, как это работает. Другие другие потоки, обслуживающие другие запросы, будут иметь одно и то же состояние. – leppie

 Смежные вопросы

  • Нет связанных вопросов^_^