UserManager错误 - 在上一个异步操作完成之前,在此上下文中启动了第二个操作

时间:2014-10-14 02:53:11

标签: c# asp.net-mvc entity-framework asp.net-mvc-5 asp.net-identity

我使用Identity v2.0.0.0,EF 6,Castle Windsor IOC容器,Microsoft SQL Server 2005 我的asp.net MVC5 Web应用程序面临此问题

我试图通过使用UserManagerExtensions,FindById()方法获取当前登录用户但是它抛出错误" System.NotSupportedException:在上一次异步操作完成之前,在此上下文中启动了第二个操作。使用'等待'确保在调用此上下文中的另一个方法之前已完成任何异步操作。任何实例成员都不能保证是线程安全的"

我从堆栈跟踪中理解的是" AsyncHelper.RunSync()"导致问题,我没有在我的代码中使用任何异步函数,但是" FindById()"使用AsyncHelper 参考 - : http://www.symbolsource.org/MyGet/Metadata/aspnetwebstacknightly/Project/Microsoft.AspNet.Identity.Core/2.0.0-beta1-140129/Release/Default/Microsoft.AspNet.Identity.Core/Microsoft.AspNet.Identity.Core/Extensions/UserManagerExtensions.cs?ImageName=Microsoft.AspNet.Identity.Core

关于此Identity错误的信息似乎很少,我在应用程序的不同部分使用当前登录用户的详细信息,当调用getCurrentLoggedInUser()函数时,这个错误似乎随机出现我的服务层。请帮帮....

我的代码和堆栈跟踪---- 注意:我在此处发现了另一个类似类型的事件:https://aspnetidentity.codeplex.com/workitem/2408

的Global.asax:

        .Register(Component
                    .For<UserManager<ApplicationUser>>()
                    .UsingFactoryMethod((kernel, creationContext) =>
                        new TempoUserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext(ASPUserDatabaseConnectionString))))
        .LifestylePerWebRequest()
                    )
        .Register(Component
                    .For<RoleManager<IdentityRole>>()
                    .UsingFactoryMethod((kernel, creationContext) =>
                        new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext(ASPUserDatabaseConnectionString))))
        .LifestylePerWebRequest()
                    )

服务层代码:

public class GenericService
{
    protected IRepository _repository;
    protected UserManager<ApplicationUser> _userManager;

    public GenericService(IRepository repository, UserManager<ApplicationUser> userManager)
    {
        _repository = repository;
        _userManager = userManager;
    }

    public ApplicationUser GetCurrentLoggedInUser()
    {
        //Error is thrown when calling this
        return _userManager.FindById(HttpContext.Current.User.Identity.GetUserId());
    }
 }

下面是堆栈跟踪,

System.NotSupportedException: A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.
   at System.Data.Entity.Internal.ThrowingMonitor.Enter()
   at System.Data.Entity.Core.Objects.ObjectQuery`1.<GetResultsAsync>d__e.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.Entity.Internal.LazyAsyncEnumerator`1.<FirstMoveNextAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.Entity.Infrastructure.IDbAsyncEnumerableExtensions.<FirstOrDefaultAsync>d__25`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   **at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.Identity.AsyncHelper.RunSync[TResult](Func`1 func)
   at Microsoft.AspNet.Identity.UserManagerExtensions.FindById[TUser,TKey](UserManager`2 manager, TKey userId)
   at Tempo.BusinessLogics.Services.GenericService.GetCurrentLoggedInUser()
   at Tempo.BusinessLogics.Services.GenericService.GetCurrentLoggedInUserID()
   at Tempo.BusinessLogics.Services.TimeService.UpdateSignOfChildDetails(EntryLog toUpdate, Boolean targetSignState)
   at Tempo.BusinessLogics.Services.TimeService.SignEntries(SignOffs sgnOffs, Byte flag)
   at Tempo.Controllers.TimeEntryController.SignOffAll(String cbxStatus)**
   at lambda_method(Closure , ControllerBase , Object[] )
   at System.Web.Mvc.ActionMethodDispatcher.<>c__DisplayClass1.<WrapVoidAction>b__0(ControllerBase controller, Object[] parameters)
   at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass48.<InvokeActionMethodFilterAsynchronouslyRecursive>b__41()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

2 个答案:

答案 0 :(得分:1)

也许您忘记了await异步函数,然后下一条语句试图在单个连接上执行两个查询?

答案 1 :(得分:0)

听起来你正在创建两个上下文,这两个上下文都是ApplicationDbContext的相同类型。当EF检测到两个同时发生的呼叫到同一个上下文时,就会出现错误。

您必须为每个Web请求仅创建一个上下文实例,或者将您的上下文拆分为它的组件部分,这样两者都可以注入而不会发生冲突。