I encountered a weird issue today which made no sense to me. Here is a summary:
Inside a method, I check for a cached item as below:
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);
//...
}
Here, the HttpContext.Current
is not null as expected inside an ASP.NET application. Then, inside the cacheRatesStatusObject
method, I check if HttpContext.Current
is null or not as below:
private void cacheRatesStatusObject(RatesStatus ratesStatus) {
//...
//Seeing if HttpContext.Current is null or not first.
//and it is null here...
if (HttpContext.Current == null)
return;
//...
}
And it is null there. No idea what is happening here. Any thoughts?
Clearly HttpContext. Current is not null only if you access it in a thread that handles incoming requests. That's why it works "when i use this code in another class of a page".
The HttpContext encapsulates all the HTTP-specific information about a single HTTP request. When an HTTP request arrives at the server, the server processes the request and builds an HttpContext object. This object represents the request which your application code can use to create the response.
It is stored in the memory of the server and the value is available for the entire lifetime of the request.
When you use async/await, the thread handling the request marks the request as incomplete and then returns to the ASP.NET thread pool
. When the awaitable completes later, another thread is assigned to run the rest of the method, however HttpContext is not migrated across threads, that's why you get null reference when calling await method.
You can pass a reference of the HttpContext to the await method, something like this:
await cacheRatesStatusObject(HttpContext.Current, ratesStatus);
However you should be very careful dealing with concurrency and race conditions, for example if the await thread locks a resource and another request thread attempts to use it then your thread pool goes boom. Most people resolve this by creating new objects and passing them into paramaterized threads instead of passing a reference of HttpContext across threads.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With