Update IAsyncDisposable.txt (#23719)

Copy/paste the [IAsyncDisposable in MVC blog post](https://asp.net-hacker.rocks/2021/03/29/aspnetcore6-03-iasyncdisposable.html) as requested in PR #23640
pull/23716/head
Juergen Gutsch 2021-11-02 23:49:33 +01:00 committed by GitHub
parent f516bd939d
commit 4a9a18cbd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 66 additions and 0 deletions

View File

@ -1 +1,67 @@
<!-- Enter contents of IAsyncDisposable now in MVC -->
The `IAsyncDisposable` is a thing since .NET Core 3.0. If I'm right, we got that together with the async streams to release those kind of streams asynchronously. Now MVC is supporting this interface as well and you can use it anywhere in your code on controllers, classes, etc. to release async resources.
## When should I use IAsyncDisposable?
When you work with asynchronous enumerators like in async steams and when you work with instances of unmanaged resources which needs resource-intensive I/O operation to release.
When implementing this interface you can use the DisposeAsync method to release those kind of resources.
## Let's try it
Let's assume we have a controller that creates and uses a `Utf8JsonWriter` which as well is a `IAsyncDisposable` resource
~~~csharp
public class HomeController : Controller, IAsyncDisposable
{
private Utf8JsonWriter _jsonWriter;
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
_jsonWriter = new Utf8JsonWriter(new MemoryStream());
}
~~~
The interface needs us to implement the `DisposeAsync` method. This should be done like this:
~~~csharp
public async ValueTask DisposeAsync()
{
// Perform async cleanup.
await DisposeAsyncCore();
// Dispose of unmanaged resources.
Dispose(false);
// Suppress GC to call the finalizer.
GC.SuppressFinalize(this);
}
~~~
This is a higher level method that calls a DisposeAsyncCore that actually does the async cleanup. It also calls the regular Dispose method to release other unmanaged resources and it tells the garbage collector not to call the finalizer. I guess this could release the instance before the async cleanup finishes.
This needs us to add another method called DisposeAsyncCore():
~~~csharp
protected async virtual ValueTask DisposeAsyncCore()
{
if (_jsonWriter is not null)
{
await _jsonWriter.DisposeAsync();
}
_jsonWriter = null;
}
~~~
This will actually dispose the async resource .
## Further reading
Microsoft has some really detailed docs about it:
* [IAsyncDisposable Interface](https://docs.microsoft.com/en-us/dotnet/api/system.iasyncdisposable?view=net-5.0)
* [Implement a DisposeAsync method](https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-disposeasync)