No.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | // ====================================================================== // Q: Is DbContext thread-safe? Can I run queries in parallel? // // No. One DbContext = one unit of work, one operation at a time. A second // concurrent operation throws InvalidOperationException: A second operation was // started on this context instance.... Common causes: Task.WhenAll on the same // context, a forgotten await, async void, a singleton holding a scoped DbContext // (captive dependency, Q5). // In a BackgroundService: create a new scope // (IServiceScopeFactory.CreateAsyncScope()) per message or iteration, so each // unit of work has its own context. Parallel queries only make sense if they are // independent and slow: each one takes a connection from the pool. // ====================================================================== // ✗ same DbContext in parallel tasks var orders = db.Orders.CountAsync(ct); var products = db.Products.CountAsync(ct); await Task.WhenAll(orders, products); // ✓ separate context per parallel operation public class DashboardQuery(IDbContextFactory<AppDbContext> factory) { public async Task<(int Orders, int Products)> GetAsync(CancellationToken ct) { await using var db1 = await factory.CreateDbContextAsync(ct); await using var db2 = await factory.CreateDbContextAsync(ct); var orders = db1.Orders.CountAsync(ct); var products = db2.Products.CountAsync(ct); return (await orders, await products); } } builder.Services.AddDbContextFactory<AppDbContext>(o => o.UseNpgsql(cs)); |