`IAsyncDisposable` & Clean Service Teardown Architecture
1Concept
Services holding asynchronous resources (network sockets, database transactions, Kafka consumers) should implement `IAsyncDisposable` (`ValueTask DisposeAsync()`) to guarantee clean teardown without thread blocking.
2Architecture Diagram
await using (var scope = provider.CreateAsyncScope())
{
var client = scope.ServiceProvider.GetRequiredService<IAsyncService>();
} // Triggers DisposeAsync() cleanly without blocking thread pool!3Code Example
C# 13 & .NET 9
using System;
using System.Threading.Tasks;
public class AsyncResourceService : IAsyncDisposable
{
public async ValueTask DisposeAsync()
{
await Task.Delay(10); // Simulates async flushing of network buffers
Console.WriteLine("Asynchronous service resource flushed and disposed cleanly.");
}
}
public class AsyncDisposeDemo
{
public static async Task Main()
{
await using (var resource = new AsyncResourceService())
{
Console.WriteLine("Service active.");
}
}
}4Expected Output
Service active. Asynchronous service resource flushed and disposed cleanly.
5Key Takeaways
- ✓Use `CreateAsyncScope()` instead of `CreateScope()` in async workflows.
- ✓Never call `.GetAwaiter().GetResult()` inside standard synchronous `Dispose()`.
- ✓Implement both `IDisposable` and `IAsyncDisposable` for dual compatibility.