在控制器操作中我正在运行
public ActionResult MyAction()
{
Task.Factory.StartNew( () =>
{
myService.ExecuteMethod( someArgs );
} );
}
该服务将调用调用其他类的其他类方法,并且在某个地方,IPrincipal
被注入到类的构造函数中。
IPrincipal
是通过HttpContext.Current.User
创建的。
由于代码位于Task
,因此它在不同的线程上运行,并且操作已返回,因此HttpContext.Current
为null
。
如果我尝试Thread.CurrentPrincipal
,它就存在,但设置为HttpContext.Current.User
以外的其他内容。此外,如果我尝试访问Thread.CurrentPrincipal.Identity.Name
,我会抛出ObjectDisposedException
。
我使用Ninject作为我的IoC容器。 IPrincipal
绑定看起来像这样
Bind<IPrincipal>().ToMethod( x => HttpContext.Current.User );
是否有办法在控制器操作中从IPrincipal
运行代码中获取正确甚至可用的Task
?
答案 0 :(得分:0)
HttpContext.Current.User
基本上类似于临时ThreadLocal
。因此,在开始在不同线程中运行的任务之前,您需要检索它的值。无法找出哪个帖子已执行Task.Factory.StartNew
并检索了它的ThreadLocal
值。
考虑一下,一旦你Task.Factory.StartNew
,webrequest甚至可以在任务实际开始之前结束。
所以你需要做的是:
IPrincipal principal = HttpContext.Current.User;
Task.Factory.StartNew( () =>
{
myService.ExecuteMethod(principal);
} );
现在,如果将IPrincipal
(ctor-)注入myService
,则 myService
会根据请求进行实例化.InTransientScope()
,{{1您的当前绑定将起作用,因为控制器是针对每个请求实例化的(另请参阅lifecycle of an asp.net mvc5 application)。
问题只会在注入.InRequestScope()
或执行Lazy<IPrincipal>
时出现(这包括使用ninject.extensions.factory,如IResolutionRoot.Get<IPrincipal>
!),因为此时{{1}可能不再有效。
我建议如果您希望答案更准确,更重要,您需要发布Minimal, Complete, and Verifiable example