Skip to content

Thread-safety issues with HttpRuntime.WebObjectActivator, HttpContext.Current and ConfigureAwait(false) #10

Description

@daiplusplus

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:UseTaskFriendlySynchronizationContext does exactly - doesn't it render this whole thing moot because it provides an AsyncLocal synchronization context? In which case, the only thing that needs fixing is to ensure .ConfigureAwait(true) (not false) 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/GetRequiredService regardless of the thread they're on - this could be done through HttpContextAccessor instead of (currently, as of 2019-12) requiring them to use HttpRuntime.WebObjectActivator as a workaround.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions