首页 > 解决方案 > 使用 EF Core dbcontext 运行异步选择时出错

问题描述

public class Person 
{
    [Key]
    public Guid Id { get; set; }
    public string FullName { get; set; }
}

public class ApplicationDbContext : DbContext 
{
    public DbSet<Person> People { get; set; }
}

public class Program 
{
    public void Main() 
    {
        using var context = new ApplicationDbContext(*configuration here*);
        var doWorks = Enumerable.Range(0, 1000).Select(x => context.People.AsNoTracking().ToArrayAsync());
        await Task.WhenAll(doWorks);
    }
}

我收到此错误:

System.InvalidOperationException: '在前一个操作完成之前,在此上下文上启动了第二个操作。这通常是由使用相同 DbContext 实例的不同线程引起的。有关如何避免 DbContext 线程问题的更多信息,请参阅https://go.microsoft.com/fwlink/?linkid=2097913

我怎样才能运行这样的多项任务并摆脱该错误?

标签: c#asynchronousdbcontextef-core-3.1

解决方案


ApplicationDbContext最简单的方法是在每个任务中创建一个新对象:

public class Program {
    public void Main() {
        var doWorks = Enumerable.Range(0, 1000).Select(async x => {
                          using var context = new ApplicationDbContext(*configuration here*);
                          await context.People.AsNoTracking().ToArrayAsync();
                      });
        await Task.WhenAll(doWorks);
    }
}

请注意,我制作了您的 lambdaasync并使用了await. 否则,上下文将在查询完成之前被释放。

如果您将此作为负载测试进行,那很好。请注意,在某些情况下,同时执行 1000 个任务可能会比其他方式执行得更差。


推荐阅读