2014-04-30 49 views
3

我正在构建一个ASP.NET WebApi 2.1应用程序需要相当于HttpContext.Items作为每个请求缓存。WebApi相当于HttpContext.Items与依赖注入

即使在IIS托管下,我也无法使用HttpContext,因为当我在服务/仓库层中执行异步工作(使用TPL调用,而不是异步/等待由于某些需要匹配的接口)时,HttpContext似乎会丢失HttpContext.Current变为null)。

我使用的是统一的3.5,并且无法实现每个请求的注入。试过HttpControllerActivator方法:

public class HttpControllerActivator : IHttpControllerActivator 
{ 
    private readonly IUnityContainer _container; 
    private readonly IHttpControllerActivator _activator; 

    public HttpControllerActivator(IUnityContainer container, IHttpControllerActivator activator) 
    { 
     _container = container; 
     _activator = activator; 
    } 

    public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) 
    { 
     IHttpController controller = _activator.Create(request, controllerDescriptor, controllerType); 
     _container.RegisterInstance<System.Net.Http.HttpRequestMessage>(request, new HierarchicalLifetimeManager()); 

     return controller; 

    } 
} 

但这注册HttpRequestMessage根容器,不是孩子一个由内而外的_activator.Create BeginScope()调用创建的。结果,我得到了并发负载下的混合请求实例。

任何想法如何解决这个问题?我使用TPL调用由于两个天登录搜索并没有发现任何真正解决这个问题......

回答

2

,不是异步/ AWAIT由于需要相匹配的一些接口

我建议你再看看asyncawait。您可以使用async作为实施的一部分,have it interoperate with other asynchronous APIs也可以使用。

这就是说,如果你想保存HttpContext.Current(以及文化等),那么关键是SynchronizationContext。我有一个MSDN article on that type,您可能会发现有帮助。因为你的代码是使用TPL,你可能会想捕捉的请求上下文到一个任务调度:

var requestContext = TaskScheduler.FromCurrentSynchronizationContext(); 

,然后用它来安排你的任务的延续。

ASP.NET异步工作的另一个重要方面是确保运行时知道您的异步工作。您可以通过调用AsyncOperationManager.CreateOperation来注册异步作业,AsyncOperation.OperationCompleted通知运行时异步作业已完成。或者,您可以捕获SynchronizationContext.Current并自行拨打SynchronizationContext.OperationStartedSynchronizationContext.OperationCompleted

再一次,再看看asyncawait,看看它是否完全有可能使用它们;他们会照顾你所有的细节。

+0

感谢您澄清'SynchronizationContext' 实际上,这些异步操作存在于我的应用程序中,因为使用了BookSleeve。由于我添加了'TaskScheduler.FromCurrentSynchronizationContext()',我不再进入继续任务。 另外,我并不是那种使用旧的AsymcOperationManager的粉丝。所有这些让我确信'async'和'await'是要走的路,尽管我真的不喜欢我必须用Task结果声明我的接口的事实! – blemasle

+0

是的,'Task'在接口中有点令人讨厌,与'IDisposable'非常相似:你必须猜测任何派生类型*是否可能是异步的(或者有需要处理的资源)。 –

+0

那么,由于[该错误](http://social.msdn.microsoft。com/Forums/en-US/967d4e61-d4ff-4b47-951b-c92f83146c79/tpl-inheritance-generics-verificationexception),我可能无法在真正需要的函数上使用异步:它们具有类型约束。 我又给了TaskScheduler一些东西,但每当我使用它,我的电话就永远挂起(我怀疑asp.net不会“看到”任务正在结束)。有任何想法吗 ? – blemasle