Вторая асинхронная операция началась ... не знаю, как - PullRequest
0 голосов
/ 22 февраля 2019

Я получаю сообщение об ошибке второй асинхронной операции, начинающейся в контексте до завершения предыдущей асинхронной операции, но я не вижу, где это происходит.Это код, который я использую.Каждый из асинхронных вызовов использует await, так что я делаю неправильно?

Это метод вызова Web API 2.

public async Task<IHttpActionResult> SendAssessmentArsAsync(int assessmentId) {
    using (var context = new LAMPEntities()) {
        var assessment = await context.EHS_Assessment_Audit.AsNoTracking().Where(x => x.id == assessmentId).FirstOrDefaultAsync();

        var arsQuery = from r in context.EHS_Assessment_Audit_AR.AsNoTracking()
                       where r.EHS_Assessment_Audit_Id == assessmentId
                       join w in context.Worker on r.Assignee_WWID equals w.WWID
                       select new {
                           w.Email,
                           w.Full_Name,
                           r.AR,
                           r.Due_Date
                       };

        var ars = await arsQuery.ToArrayAsync();

        var lab = from s in context.Lab_Space.AsNoTracking()
                  where s.id == assessment.Lab_Space.id
                  join w in context.Worker.AsNoTracking() on s.Contact_WWID equals w.WWID
                  where w.Email != null
                  join d_join in context.Worker.AsNoTracking() on s.Delegate equals d_join.WWID into d_grp
                  from d in d_grp.DefaultIfEmpty()
                  select new {
                      Owner = w.Email,
                      Delegate = d.Email,
                      Barcode = s.Entry_Bar_Code,
                      Label = s.Floor_Space_Label,
                      Id = s.id
                  };

        var mails = await lab.FirstAsync();

Когда он попадает в последнюю строку, это гдеон вызывает исключение.

Сообщение об исключении:

Вторая операция, запущенная в этом контексте перед завершением предыдущей асинхронной операции.Используйте 'await', чтобы убедиться, что все асинхронные операции завершены, прежде чем вызывать другой метод в этом контексте.Любые члены экземпляра не гарантируют поточнобезопасность.

Вот исключение, как показано с помощью вызова веб-службы:

b__a()
 at System.Data.Entity.Core.Objects.ObjectContext.d__3d`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
 at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.d__9`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
 at System.Data.Entity.Utilities.TaskExtensions.CultureAwaiter`1.GetResult()
 at System.Data.Entity.Core.Objects.ObjectQuery`1.d__e.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
 at System.Data.Entity.Utilities.TaskExtensions.CultureAwaiter`1.GetResult()
 at System.Data.Entity.Internal.LazyAsyncEnumerator`1.d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
 at System.Data.Entity.Infrastructure.IDbAsyncEnumerableExtensions.d__1d`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
 at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
 at LabSORService.Controllers.EHSController.d__21.MoveNext() in ...\\Controllers\\EHSController.cs:line 854
--- End of stack trace from previous location where exception was thrown ---
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
 at System.Threading.Tasks.TaskHelpersExtensions.d__1`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
 at System.Web.Http.Controllers.ApiControllerActionInvoker.d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
 at System.Web.Http.Controllers.ActionFilterResult.d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
 at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__15.MoveNext()" }
{
  "message": "An error has occurred.",
  "exceptionMessage": "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.",
  "exceptionType": "System.NotSupportedException",
  "stackTrace": "   at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.TryGetFieldOrPropertyValue(MemberExpression me, Object instance, Object& memberValue)
   at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.TryEvaluatePath(Expression expression, ConstantExpression& constantExpression)
   at System.Data.Entity.Core.Objects.ELinq.QueryParameterExpression.EvaluateParameter(Object[] arguments)
   at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClassc.

1 Ответ

0 голосов
/ 22 февраля 2019

Скорее всего

where s.id == assessment.Lab_Space.id

запускает отложенную загрузку Lab_Space свойства навигации в неподходящее время.

Предполагается, что у вас нет явного свойства FK, например Lab_Space_Id (если у вас естьпросто используйте его вместо Lab_Space.id), либо загрузите его (желательно):

var assessment = await context.EHS_Assessment_Audit.AsNoTracking()
    .Include(x => x.Lab_Space) // <--
    .Where(x => x.id == assessmentId).FirstOrDefaultAsync();

или оцените его вне запроса:

var labSpaceId = assessment.Lab_Space.id; // <--
var lab = from s in context.Lab_Space.AsNoTracking()
          where s.id == labSpaceId // <--
          ...

Обратите внимание, что в исходном запросе, assessment.Lab_Space доступ только записан в дереве выражения запроса.Фактическая оценка (следовательно, запуск ленивой загрузки) происходит как часть выполнения запроса.

...