1

I asked before a question这里,我读了关于多线程的这个问题/答案,我知道这些解决方案。但今天我遇到了一个新问题。当我们使用命令(或者我们可以访问原始代码来管理和修改它)时,上面的答案中提出的async-decorator就可以工作。但是当MVC本身创建一个新线程时,我们能做什么?例如我有一个自定义角色提供(与DbContext作品),我得到这个错误:SimpleInjector和System.Web.Mvc.Async线程

The operation cannot be completed because the DbContext has been disposed.

这里是堆栈跟踪:

[InvalidOperationException: The operation cannot be completed because the DbContext has been disposed.]

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

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

System.Data.Entity.Internal.Linq.DbQueryProvider.Execute(Expression expression) +22

System.Linq.Queryable.Any(IQueryable 1 source, Expression 1 predicate) +265

MyProject.MyRoleProvider.IsUserInRole(String username, String roleName) in ...

System.Web.Security.Roles.IsUserInRole(String username, String roleName) +263

MyProject.MyPrincipal.IsInRole(String role) in ...

System.Linq.Enumerable.Any(IEnumerable 1 source, Func 2 predicate) +146

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

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

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

System.Web.Mvc.Async.<>c__DisplayClass25.b__1e(AsyncCallback asyncCallback, Object asyncState) +446

System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130

System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +302

System.Web.Mvc.<>c__DisplayClass1d.b__17(AsyncCallback asyncCallback, Object asyncState) +30

System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130

System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +382

System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130

System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +317

System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +15

System.Web.Mvc.<>c__DisplayClass8.b__2(AsyncCallback asyncCallback, Object asyncState) +71

System.Web.Mvc.Async.WrappedAsyncResult`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130

System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +249

System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50

System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16

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

System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

正如你所看到的,MyProject.MyRoleProvider.IsUserInRole异步调用的,我做到了不是启动它,而是通过MVC本身调用异步。所以我没有任何控制权。我的提供商ctor是:

public MyRoleProvider(){ _context = MyIoCWrapper.GetService(); }

看来,当实例化MyRoleProviderHttpContext不为空,而当叫IsInRoleHttpContext为空。 如果我想开始一个新的生命范围,它只会被使用一次,如果MVC启动一个新的线程,我也会有一个新的DbContext。我很困惑找到解决方案。你有没有? 如何为所有后台线程启动新的生命范围-I启动它们还是MVC启动它们?

回答

1

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

您可能在应用程序的web.config中注册了您的MyRoleProvider,或者可能通过代码注册了它。无论如何,MyRoleProvider是一个单身人士,在应用程序的整个生命周期中,这个类只有一个实例。

然而,MyRoleProvider取决于DbContext其中有一种生活方式,更短(每个Web请求或混合在你的情况下),这意味着你的MyRoleProver的寿命期间,您将无法缓存这些DbContext,因为这将“促进'DbContext也是单身人士的生活方式。 _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); 
} 
+1

OSh !!!!是的是的你是对的。我忘了提供者是单身人士):对于一个无关的问题抱歉。我对自己很难,虽然这是一个简单明了的情况 –