Ошибка UserManager. Вторая операция началась в этом контексте до завершения предыдущей асинхронной операции

Я столкнулся с этой проблемой с моим веб-приложением asp.net MVC5, используя Identity v2.0.0.0, EF 6, Контейнер IOC Castle Windsor, Microsoft SQL Server 2005

Я пытаюсь получить текущий вход в систему User с помощью метода UserManagerExtensions, FindById(), но он выдает ошибку "System.NotSupportedException: вторая операция, запущенная в этом контексте до завершения предыдущей асинхронной операции. Используйте" ожидание ", чтобы все асинхронные операции были завершены до вызова другого метода в этом контексте. Любые члены экземпляра не гарантируются как потокобезопасные"

Что я понял из трассировки стека, так это то, что "AsyncHelper.RunSync()" вызывает проблемы, я не использую какие-либо функции asynch в моем коде, но "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()
 )
</identityrole></identityrole></rolemanager<identityrole></applicationuser></applicationuser></usermanager<applicationuser>

Код уровня сервиса:

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());
 }
 }
</applicationuser></applicationuser>

Ниже показана трассировка стека,

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)
</beginprocessrequest></beginexecute></beginexecutecore></begininvokeaction></begininvokeaction></begininvokeactionmethodwithfilters></invokeactionmethodfilterasynchronouslyrecursive></invokeactionmethodfilterasynchronouslyrecursive></begininvokesynchronousactionmethod></wrapvoidaction></firstordefaultasync></firstmovenextasync></getresultsasync>
1 ответ

Похоже, вы создаете два контекста, оба из которых имеют один и тот же тип ApplicationDbContext. Когда EF обнаруживает два вызова, происходящих одновременно с одним и тем же контекстом, вы получаете свою ошибку.

Вам нужно либо создать только один экземпляр вашего контекста для каждого веб-запроса, либо разделить его контекст на его составные части, чтобы оба они могли быть введены без конфликта.

licensed under cc by-sa 3.0 with attribution.