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

tug*_*erk 5 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);

    //...
}
Run Code Online (Sandbox Code Playgroud)

这里,HttpContext.CurrentASP.NET应用程序中的预期值不是预期的.然后,在cacheRatesStatusObject方法内部,我检查是否HttpContext.Current为null,如下所示:

private void cacheRatesStatusObject(RatesStatus ratesStatus) {

    //...

    //Seeing if HttpContext.Current is null or not first.
    //and it is null here...
    if (HttpContext.Current == null)
        return;

    //...
}
Run Code Online (Sandbox Code Playgroud)

它在那里是空的.不知道这里发生了什么.有什么想法吗?

Kam*_*eri 4

当您使用 async/await 时,处理请求的线程会将请求标记为未完成,然后返回到ASP.NET thread pool. 当等待稍后完成时,会分配另一个线程来运行该方法的其余部分,但是 HttpContext 不会跨线程迁移,这就是为什么在调用等待方法时会得到空引用。

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

await cacheRatesStatusObject(HttpContext.Current,  ratesStatus);
Run Code Online (Sandbox Code Playgroud)

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