dotnet runtime_error ai_generated true

System.InvalidOperationException: 在此上下文实例上完成上一个操作之前,又启动了第二个操作。这通常是由不同线程同时使用同一 DbContext 实例引起的。

System.InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext.

ID: dotnet/ef-core-sync-query-on-async-context

其他格式: JSON · Markdown 中文 · English
85%修复率
88%置信度
1证据数
2023-03-15首次发现

版本兼容性

版本状态引入弃用备注
Entity Framework Core 3.1 active — — —
Entity Framework Core 5.0 active — — —
Entity Framework Core 6.0 active — — —
Entity Framework Core 7.0 active — — —
Entity Framework Core 8.0 active — — —

根因分析

DbContext 实例不是线程安全的,多个线程同时使用它,通常是由于同步调用阻塞异步操作或 DI 注册不当(例如,使用 Singleton 代替 Scoped)导致的。

English

A DbContext instance is not thread-safe and is being used concurrently from multiple threads, typically due to synchronous calls blocking async operations or improper DI registration (e.g., Singleton instead of Scoped).

generic

官方文档

https://learn.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency

解决方案

  1. Ensure DbContext is registered as Scoped in DI (default). For ASP.NET Core: services.AddDbContext<MyDbContext>(options => options.UseSqlServer(connectionString));
  2. Avoid mixing sync and async calls on the same DbContext. Use async methods (e.g., ToListAsync() instead of ToList()) consistently. If you must use sync, create a separate DbContext instance.
  3. Use DbContext pooling for high-throughput scenarios: services.AddDbContextPool<MyDbContext>(options => options.UseSqlServer(connectionString), poolSize: 128);

无效尝试

常见但无效的做法:

  1. Changing DbContext registration to Singleton to reuse the same instance globally. 95% 失败

    Singleton DbContext is not thread-safe and will cause the same error under concurrent requests; it also leads to stale data and memory leaks.

  2. Adding locks around all DbContext usage to serialize access. 85% 失败

    Locks defeat the purpose of async I/O and can cause deadlocks or severe performance degradation under load.

  3. Setting DbContext.PoolSize to a large number without configuring AddDbContextPool. 90% 失败

    PoolSize only applies when using DbContext pooling; without AddDbContextPool, it has no effect.