Asp.net mvc 从控制器操作运行的任务中的Principal.Identity.Name

Asp.net mvc 从控制器操作运行的任务中的Principal.Identity.Name,asp.net-mvc,task-parallel-library,ninject,task,Asp.net Mvc,Task Parallel Library,Ninject,Task,在控制器操作中,我正在运行 public ActionResult MyAction() { Task.Factory.StartNew( () => { myService.ExecuteMethod( someArgs ); } ); } 服务将调用调用其他类的其他类方法,然后在某个地方,一个IPrincipal被注入到类的构造函数中 IPrincipal是通过执行HttpContext.Current.User创建的 由于代码位于任务中,因此

在控制器操作中,我正在运行

public ActionResult MyAction()
{
    Task.Factory.StartNew( () =>
    {
        myService.ExecuteMethod( someArgs );
    } );
}
服务将调用调用其他类的其他类方法,然后在某个地方,一个IPrincipal被注入到类的构造函数中

IPrincipal是通过执行HttpContext.Current.User创建的

由于代码位于任务中,因此它在不同的线程上运行,并且该操作返回的HttpContext.Current为null

如果我尝试执行Thread.CurrentPrincipal,则它存在,但设置为HttpContext.Current.User之外的内容。另外,如果我尝试访问Thread.CurrentPrincipal.Identity.Name,就会抛出ObjectDisposedException

我正在使用Ninject作为IoC容器。IPrincipal绑定如下所示

Bind<IPrincipal>().ToMethod( x => HttpContext.Current.User );
有没有办法从控制器操作中的任务运行的代码中获取正确的甚至可用的IPrincipal?

HttpContext.Current.User基本上类似于临时ThreadLocal。因此,在启动在不同线程中运行的任务之前,需要检索它的值。无法找出哪个线程执行了Task.Factory.StartNew并检索其ThreadLocal值。 考虑一下,一旦你完成任务,Fask.StEngEngEngEngEngEngEngestWebEngress甚至可以在任务真正启动之前结束。 因此,您需要做的是:

IPrincipal principal = HttpContext.Current.User;

Task.Factory.StartNew( () =>
{
    myService.ExecuteMethod(principal);
} );
但是,现在如果将IPrincipal注入到myService中,并且myService根据每个请求进行实例化。InTransientScope、.InRequestScope,则您当前的绑定将起作用,因为每个请求都会实例化控制器,请参见

该问题仅在注入Lazy或执行IResolutionRoot时出现。Get包括使用ninject.extensions.factory,如Func!,因为此时HttpContext.Current.User可能不再有效


我建议,如果你想要一个更准确、更切题的答案,你需要贴一张

这正是我所想的。我想也许我遗漏了一些我可以利用的东西。哦,好吧。我现在只是将其传递到方法调用中。