c# - EF 6 – 在 SaveChangesAsync 方法中异步执行 SQL 命令抛出 NotSupportedException

标签 c# .net entity-framework async-await entity-framework-6

我已经覆盖了 DbContextSaveChangesAsync 方法来调用一堆存储过程。首先,我调用 DbContextSaveChangesAsync,然后为每个更改的实体执行一个存储过程。

等待所有异步方法调用。

这是 EF 抛出的异常:

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.EnsureNotEntered()
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreCommandAsync(TransactionalBehavior transactionalBehavior, String commandText, CancellationToken cancellationToken, Object[] parameters)
   at System.Data.Entity.Internal.InternalContext.ExecuteSqlCommandAsync(TransactionalBehavior transactionalBehavior, String sql, CancellationToken cancellationToken, Object[] parameters)
   at System.Data.Entity.Database.ExecuteSqlCommandAsync(TransactionalBehavior transactionalBehavior, String sql, CancellationToken cancellationToken, Object[] parameters)
   at System.Data.Entity.Database.ExecuteSqlCommandAsync(String sql, CancellationToken cancellationToken, Object[] parameters)
   at System.Data.Entity.Database.ExecuteSqlCommandAsync(String sql, Object[] parameters)
   at Common.Dal.AuditDbContext.<>c__DisplayClass20_0.<WriteAuditsParallelAsync>b__0(Audit x) in 
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Threading.Tasks.Task.WhenAll[TResult](IEnumerable`1 tasks)
   at Common.Dal.AuditDbContext.<WriteAuditsParallelAsync>d__20.MoveNext() in
--- 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.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Common.Dal.AuditDbContext.<SaveToDatabaseAsync>d__18.MoveNext() in

这是我的代码:

public override Task<Int32> SaveChangesAsync( CancellationToken cancellationToken )
{
    var modified = this.GetModifiedOrDeletedEntities();
    var added = this.GetAddedEntities();

    var audits = AuditService.GetAudits( GetObjectStateManager(), modified );

    //Call SaveChangesAsync
    var result = await base.SaveChangesAsync( cancellationToken );

    audits.AddRange( AuditService.GetAudits( GetObjectStateManager(), added ) );

    //Call stored prcedures
    await WriteAuditsAsync( audits, user );

    return result;
}

private async Task WriteAuditsAsync(List<Audit> audits, String user)
{
    foreach ( var audit in audits)
    {
        try
        {
            ...
            //Execute SQL command 
            await Database.ExecuteSqlCommandAsync(myCommand, myParameters);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
    }
}

为什么 EF 抛出这个异常?

最佳答案

查看异常,您可以看到您正在 WriteAuditsParallelAsync 中调用 Task.WhenAll,这意味着您同时开始多个异步操作,并且您异步等待所有这些完成。

您不能在 EF 上下文中同时执行多个操作,这就是它抛出的原因。

您可以通过依次启动和等待这些操作来解决这个问题。

关于c# - EF 6 – 在 SaveChangesAsync 方法中异步执行 SQL 命令抛出 NotSupportedException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33563655/

相关文章:

.net - DateTime.Now 抛出异常

.NET UserControl继承父窗体背景

c# - 将 Entity Framework Linq 查询打印为字符串

C# 继承挑战

c# - LocalReport.SetParameters Exception 试图设置此报告中未定义的报告参数 'ParameterName'

c# - 如何将数据库查询结果转换为数组?

c# - EntityFunctions.TruncateTime 和 DbFunctions.TruncateTime 方法有什么区别?

不同 child 的C#继承倍数

c# - LINQ 搜索中的 mscorlib.dll 中出现类型为 'System.OutOfMemoryException' 的未处理异常

c# - 无效的列名 C#