Dependency injection SimpleInjector和System.Web.Mvc.Async线程

Dependency injection SimpleInjector和System.Web.Mvc.Async线程,dependency-injection,inversion-of-control,simple-injector,Dependency Injection,Inversion Of Control,Simple Injector,我在这里阅读了关于多线程的问题/答案,我知道这些解决方案。但今天我遇到了一个新问题。当我们使用命令时(或者在我们可以访问原始代码来管理和修改它的地方),上面答案中建议的异步装饰器可以工作。但是当MVC自己创建一个新线程时,我们能做什么呢?e、 g.我有一个自定义角色提供程序(与DbContext一起使用),我得到以下错误: 无法完成该操作,因为DbContext已被释放 这里是堆栈跟踪: [InvalidOperationException:无法完成操作,因为DbContext已被释放。] Sy

我在这里阅读了关于多线程的问题/答案,我知道这些解决方案。但今天我遇到了一个新问题。当我们使用命令时(或者在我们可以访问原始代码来管理和修改它的地方),上面答案中建议的异步装饰器可以工作。但是当MVC自己创建一个新线程时,我们能做什么呢?e、 g.我有一个自定义角色提供程序(与
DbContext
一起使用),我得到以下错误:

无法完成该操作,因为DbContext已被释放

这里是堆栈跟踪:

[InvalidOperationException:无法完成操作,因为DbContext已被释放。]

System.Data.Entity.Internal.InternalContext.CheckContextNotDisposed()+67

System.Data.Entity.Internal.LazyInternalContext.InitializeContext()+34

System.Data.Entity.Internal.Linq.DbQueryProvider.Execute(表达式)+22

System.Linq.Queryable.Any(IQueryable
1源代码,表达式
1谓词)+265

MyProject.MyRoleProvider.IsUserInRole(字符串用户名,字符串角色名)位于…

System.Web.Security.Roles.IsUserInRole(字符串username,字符串roleName)+263

MyProject.MyPrincipal.IsInRole(字符串角色)位于

System.Linq.Enumerable.Any(IEnumerable
1源代码,Func
2谓词)+146

System.Web.Mvc.AuthorizeAttribute.AuthorizeCore(HttpContextBase httpContext)+200

System.Web.Mvc.AuthorizationAttribute.OnAuthorization(AuthorizationContext filterContext)+159

System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext ControllerContext,IList`1 filters,ActionDescriptor ActionDescriptor)+96

System.Web.Mvc.Async.c_uudisplayClass25.b_uu1E(AsyncCallback AsyncCallback,Object asyncState)+446

System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(异步回调,对象状态,Int32超时)+130

System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext ControllerContext,String actionName,AsyncCallback回调,对象状态)+302

System.Web.Mvc.c_uudisplayClassad.b_uu17(异步回调,对象异步状态)+30

System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(异步回调,对象状态,Int32超时)+130

System.Web.Mvc.Controller.BeginExecuteCore(异步回调,对象状态)+382

System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(异步回调,对象状态,Int32超时)+130

System.Web.Mvc.Controller.BeginExecute(RequestContext-RequestContext,异步回调,对象状态)+317

System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext RequestContext,AsyncCallback回调,对象状态)+15

System.Web.Mvc.c_uuudisplayClass8.b_uuu2(异步回调,对象异步状态)+71

System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(异步回调,对象状态,Int32超时)+130

System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext,异步回调,对象状态)+249

System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext HttpContext,异步回调,对象状态)+50

System.Web.Mvc.MvcHandler.System.Web.IHTTPassynchandler.BeginProcessRequest(HttpContext上下文,异步回调cb,对象外部数据)+16

System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+301

System.Web.HttpApplication.ExecuteStep(IExecutionStep步骤,布尔值&同步完成)+155

如您所见,
MyProject.MyRoleProvider.IsUserInRole
是异步调用的,我没有启动它,而是由MVC本身异步调用。所以我无法控制它。我的建议是:

公共MyRoleProvider(){ _context=MyIoCWrapper.GetService(); }

MyRoleProvider
实例化时,
HttpContext
似乎不为null,而当调用
IsInRole
时,
HttpContext
则为null。 如果我想启动一个新的生命范围,它只会被使用一次,如果MVC启动一个新线程,我也会有一个新的
DbContext
。我对找到解决办法感到困惑。你有吗?
如何为所有后台线程启动一个新的生命范围?我启动它们还是MVC启动它们?

您的问题实际上与异步运行控制器无关,而是控制对象生命周期的一般问题

您可能在应用程序的web.config中注册了
MyRoleProvider
,或者通过代码注册了它。另外,
MyRoleProvider
是一个单实例,在应用程序的生命周期中只有该类的一个实例

然而,
MyRoleProvider
依赖于生活方式较短的
DbContext
,这意味着在
MyRoleProver
的生命周期内无法缓存该
DbContext
,因为这将“促进”单身人士的生活方式。
\u context=MyIoCWrapper.GetService()行似乎表明您正在缓存
DbContext

在这种情况下,您必须解析每个方法调用的
DbContext
实例。因此,您的
IsUserInRole
将如下所示:

public bool IsUserInRole(String username, String roleName)
{
    var context = MyIoCWrapper.GetService();
    return context.Roles
        .Any(r => r.Name == roleName && r.User.Name == username);
}

实际上,您的问题与异步运行控制器无关,而是控制obj生命周期的一般问题