# 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`
- **Domain:** dotnet
- **Category:** runtime_error
- **Verification:** ai_generated
- **Fix Rate:** 85%

## Root Cause

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).

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| 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 | — | — |

## Workarounds

1. **Ensure DbContext is registered as Scoped in DI (default). For ASP.NET Core: services.AddDbContext<MyDbContext>(options => options.UseSqlServer(connectionString));** (90% success)
   ```
   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.** (85% success)
   ```
   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);** (80% success)
   ```
   Use DbContext pooling for high-throughput scenarios: services.AddDbContextPool<MyDbContext>(options => options.UseSqlServer(connectionString), poolSize: 128);
   ```

## Dead Ends

- **Changing DbContext registration to Singleton to reuse the same instance globally.** — Singleton DbContext is not thread-safe and will cause the same error under concurrent requests; it also leads to stale data and memory leaks. (95% fail)
- **Adding locks around all DbContext usage to serialize access.** — Locks defeat the purpose of async I/O and can cause deadlocks or severe performance degradation under load. (85% fail)
- **Setting DbContext.PoolSize to a large number without configuring AddDbContextPool.** — PoolSize only applies when using DbContext pooling; without AddDbContextPool, it has no effect. (90% fail)
