5

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

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

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.CurrentASP.NET 应用程序中,它不是预期的 null。然后,在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;

    //...
}

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

4

3 回答 3

4

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

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

await cacheRatesStatusObject(HttpContext.Current,  ratesStatus);

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

于 2012-06-02T19:48:57.370 回答
1

传递实例很糟糕。

请改用 .NET 4 MemoryCache 类。

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

于 2013-02-13T20:29:52.107 回答
0

它本身不会为空。

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

正如另一个答案所建议的,只需传递实例。

于 2012-06-02T19:52:37.337 回答