检查Cache后,System.Web.HttpContext.Current自身为空

时间:2012-05-11 15:01:41

标签: asp.net caching httpcontext system.web

我今天遇到了一个奇怪的问题,对我来说毫无意义。以下是摘要:

在方法中,我检查一个缓存的项目如下:

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 个答案:

答案 0 :(得分:4)

当您使用async / await时,处理请求的线程将请求标记为不完整,然后返回ASP.NET thread pool。当awaitable稍后完成时,会分配另一个线程来运行方法的其余部分,但HttpContext不会跨线程迁移,这就是调用await方法时获得null引用的原因。

您可以将HttpContext的引用传递给await方法,如下所示:

await cacheRatesStatusObject(HttpContext.Current,  ratesStatus);

但是,您应该非常小心处理并发和竞争条件,例如,如果await线程锁定资源而另一个请求线程尝试使用它,那么您的线程池就会蓬勃发展。大多数人通过创建新对象并将它们传递给参数化线程来解决这个问题,而不是跨线程传递HttpContext的引用。

答案 1 :(得分:1)

传递实例很糟糕。

请改用.NET 4 MemoryCache类。

http://stevescodingblog.co.uk/net4-caching-with-mvc/

答案 2 :(得分:0)

它本身并不为空。

HttpContext仅以'线程静态'方式存储。

正如其他答案所示,只需传递实例。