Thread-safety issues with `HttpRuntime.WebObjectActivator`, `HttpContext.Current` and `ConfigureAwait(false)`
In my main project that uses AspNetDependencyInjection, I noticed at least one places where after an await someTask.ConfigureAwait(false); a call is made to HttpContext.Current (and possibly HttpRuntime.WebObjectActivator) to instantiate a Control subclass (with injected constructor services) when it came to rendering the page, which fails because the code is running on a separate thread from the thread that "owns" the HttpContext. There may also be issues with this project's HttpContextAccessor too.
There could be a multiple reasons for this - warrants further investigation.
But I did think of a way for threads to get the original HttpContext reference regardless of thread: by storing an immutable thread-id inside HttpContextAccessor, and using a ConcurrentDictionary that maps thread-ids to WeakReference wrappers of HttpContext. The thread-it can be found
- See what
aspnet:UseTaskFriendlySynchronizationContextdoes exactly - doesn't it render this whole thing moot because it provides anAsyncLocalsynchronization context? In which case, the only thing that needs fixing is to ensure.ConfigureAwait(true)(notfalse) is used before resuming in the render section of a request lifetime? - If there isn't a request-id feature built-in to ASP.NET, consider adding our own inside the DI
HttpModule. - I still need to get around to exposing better direct access to the global and scoped DI container so services and components can safely use
GetService/GetRequiredServiceregardless of the thread they're on - this could be done throughHttpContextAccessorinstead of (currently, as of 2019-12) requiring them to useHttpRuntime.WebObjectActivatoras a workaround.
Hi, I just read this article before your issue. I think they are related, although I don't understand 100% yet. My apologies if It is something known. Thanks for your work