本文介绍了在使用的WebAPI是HttpContext.Current由于异步的危险的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是与此相关的一个位:WebApi相当于HttpContext.Items与依赖注入。

我们希望使用Ninject中的WebAPI地区使用HttpContext.Current注入一类。

我关心的是,这可能是的非常危险,如的WebAPI(的一切吗?的)是异步。

请纠正我,如果我错了,在这点,这是我调查至今:


  1. HttpContext.Current获得通过线程的当前上下文(我看着进入实施直接)。


  2. 使用HttpContext.Current异步任务里面是不可能的,因为它可以在另一个线程上运行。


  3. 的WebAPI使用IHttpController与方法任务< Htt的presponseMessage> ExecuteAsync =>每一个请求是异步=>您不能使用HttpContext.Current操作方法里面。它甚至可能发生,更多的请求被coicidence相同的线程上执行。


  4. 有关注射的东西创建控制器为构造IHttpControllerActivator用于与同步方式 IHttpController创建。这一点,在那里与ninject其所有的依赖造成控制器。




  • 如果我在所有这些4点正确,操作方法或任何层内部使用HttpContext.Current下面是非常危险的,可以有意想不到的效果。我看到很多SO接受的答案正是这种提示的。恕我直言,这可以工作了一段时间,但在负载下会失败。


  • 但使用DI创建一个控制器及其依赖的时候,它是确定的,因为这个运行在一个独立的线程。 我可以摆脱在构造函数中的HttpContext值,这将是安全的吗?。我不知道如果在单个线程创建为每个请求的每个控制器,因为这可能重物,其中从IIS中的所有线程可以消耗下造成的问题。


只是为了解释为什么我要注入HttpContext的东西:


  • 一个解决办法是让在控制器的操作方法的要求,并通过所需要的价值的所有图层作为参数,直到它在code使用深的地方。

  • 我们的解决方案通缉:所有的层不受此受其影响,我们可以在code深的地方使用注入的请求(例如,在一些ConfigurationProvider这是依赖于URL)

    请给我你的意见,如果我错了完全以我还是建议是正确的,因为这个主题似乎是很复杂的。 Thx提前!



解决方案

It would be more correct to say that HttpContext is applied to a thread; or a thread "enters" the HttpContext.

Not at all; the default behavior of async/await will resume on an arbitrary thread, but that thread will enter the request context before resuming your async method.


The key to this is the SynchronizationContext. I have an MSDN article on the subject if you're not familiar with it. A SynchronizationContext defines a "context" for a platform, with the common ones being UI contexts (WPF, WinPhone, WinForms, etc), the thread pool context, and the ASP.NET request context.

The ASP.NET request context manages HttpContext.Current as well as a few other things such as culture and security. The UI contexts are all tightly associated with a single thread (the UI thread), but the ASP.NET request context is not tied to a specific thread. It will, however, only allow one thread in the request context at a time.

The other part of the solution is how async and await work. I have an async intro on my blog that describes their behavior. In summary, await by default will capture the current context (which is SynchronizationContext.Current unless it is null), and use that context to resume the async method. So, await is automatically capturing the ASP.NET SynchronizationContext and will resume the async method within that request context (thus preserving culture, security, and HttpContext.Current).

If you await ConfigureAwait(false), then you're explicitly telling await to not capture the context.

Note that ASP.NET did have to change its SynchronizationContext to work cleanly with async/await. You have to ensure that the application is compiled against .NET 4.5 and also explicitly targets 4.5 in its web.config; this is the default for new ASP.NET 4.5 projects but must be explicitly set if you upgraded an existing project from ASP.NET 4.0 or earlier.

You can ensure these settings are correct by executing your application against .NET 4.5 and observing SynchronizationContext.Current. If it is AspNetSynchronizationContext, then you're good; if it's LegacyAspNetSynchronizationContext, then the settings are wrong.

As long as the settings are correct (and you are using the ASP.NET 4.5 AspNetSynchronizationContext), then you can safely use HttpContext.Current after an await without worrying about it.

这篇关于在使用的WebAPI是HttpContext.Current由于异步的危险的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 21:40