Should you elide async/await in C# and return the Task directly? The using + DbContext pitfall

C# Async & Multithreading November 13, 2026 csharp

Returning the Task without async saves the state machine, but the gain is minimal.

csharp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// ======================================================================
// Q: Should you elide async/await and just return the Task?
//
// Returning the Task without async saves the state machine, but the gain is
// minimal. It breaks with using and try/catch, though, and validation exceptions
// are thrown synchronously instead of inside the Task. Rule: await by default.
// Elide only in simple pass-through overloads.
// ======================================================================

// ✗ Bug: the using disposes the DbContext BEFORE the query completes
public Task<List<Order>> GetOrdersAsync(CancellationToken ct)
{
    using var db = dbFactory.CreateDbContext();
    return db.Orders.ToListAsync(ct);   // ObjectDisposedException: the using runs here, not at the end of the query
}

// ✓ With await, Dispose happens after the query finishes
public async Task<List<Order>> GetOrdersAsync(CancellationToken ct)
{
    await using var db = await dbFactory.CreateDbContextAsync(ct);
    return await db.Orders.ToListAsync(ct);
}