Dependency injection SimpleInjector和System.Web.Mvc.Async线程
我在这里阅读了关于多线程的问题/答案,我知道这些解决方案。但今天我遇到了一个新问题。当我们使用命令时(或者在我们可以访问原始代码来管理和修改它的地方),上面答案中建议的异步装饰器可以工作。但是当MVC自己创建一个新线程时,我们能做什么呢?e、 g.我有一个自定义角色提供程序(与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
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(IQueryable1源代码,表达式1谓词)+265
MyProject.MyRoleProvider.IsUserInRole(字符串用户名,字符串角色名)位于…
System.Web.Security.Roles.IsUserInRole(字符串username,字符串roleName)+263
MyProject.MyPrincipal.IsInRole(字符串角色)位于
System.Linq.Enumerable.Any(IEnumerable1源代码,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生命周期的一般问题