Take advantage of the IAsyncDisposable interface to dispose of objects in a non-blocking way and make your .NET applications more efficient. Credit: Zachary Staines Dispose and Finalize are two methods for releasing resources held by .NET and .NET Core applications executing in the context of the CLR. If your application contains unmanaged resources, you must write the necessary code to release those resources explicitly. Since finalization is non-deterministic and finalizers are expensive in terms of resource consumption, the Dispose method is preferred over a finalizer. You can use the Dispose method on any type that implements the IDisposable interface. Eventually, with the advent of asynchronous programming, .NET needed an asynchronous counterpart to IDisposable. Thus the IAsyncDisposable interface was introduced. This article discusses the IAsyncDisposable interface and how to work with it in C#. To work with the code examples provided in this article, you should have Visual Studio 2022 installed in your system. If you don’t already have a copy, you can download Visual Studio 2022 here. Create a console application project in Visual Studio 2022 First off, let’s create a .NET Core console application project in Visual Studio. Assuming Visual Studio 2022 is installed in your system, follow the steps outlined below to create a new .NET Core console application project. Launch the Visual Studio IDE. Click on “Create a new project.” In the “Create a new project” window, select “Console App” from the list of templates displayed. Click Next. In the “Configure your new project” window shown next, specify the name and location for the new project. In the “Additional Information” window, select .NET 6.0 as the runtime and click Next Click Create. This will create a new .NET Core console application project. We’ll use this project to work with the IAsyncDisposable interface in the subsequent sections of this article. From IDisposable to IAsyncDisposable The IDisposable interface has been around since the early days of the .NET Framework, from .NET Framework 1.0 to be precise. You probably have used this interface often when designing your classes in .NET and .NET Core. If your class implements the IDisposable interface, it is advisable that you should call the Dispose method explicitly. However, many new features have been added to .NET Framework over the years. Because multithreading was resource intensive, asynchronous programming was added to the mix. Asynchronous programming can improve the performance and responsiveness of your application because the calling thread can continue to perform other operations while the method called asynchronously continues to execute. Types that implement the IDisposable interface free up resources synchronously and therefore can block other threads running on the system. Moreover, if you fail to dispose an asynchronous disposable resource, it could lead to deadlocks as well. The IAsyncDisposable interface addresses the need for freeing up resources asynchronously. When should you use IAsyncDisposable? You should use IAsyncDisposable only when you have a class that needs to release resources asynchronously. In other words, you should use IAsyncDisposable if your class (or any of its subclasses) allocates resources that also implement IAsyncDisposable. In which case, you should ensure that the DisposeAsync method is declared as virtual in the base class. As an example, you should take advantage of IAsyncDisposable when you’re working with asynchronous streams and instances of unmanaged resources that are resource-intensive and should be cleaned up. You can leverage the DisposeAsync method of this interface to release such resources. Implementing the IAsyncDisposable interface The IAsyncDisposable interface defines the DisposeAsync method. Note that the DisposeAsync method returns a ValueTask which represents an asynchronous dispose operation. Note that any non-sealed class, i.e., any class that can be extended, should have an additional method called DisposeAsyncCore that also returns a ValueTask. A typical DisposeAsync implementation should look like this: public async ValueTask DisposeAsync() { // Perform async cleanup here await DisposeAsyncCore(); // Dispose all unmanaged resources Dispose(false); GC.SuppressFinalize(this); } So, you can write your asynchronous code as in the example given below, and the objects of the operation will be disposed asynchronously. await using (SqlConnection dbConnection = new SqlConnection(connectionString)) { // The connection instance will be disposed asynchronously when the // program encounters the end of the using block. } Note the await keyword used before the using statement in the preceding code snippet. The await keyword here informs the using block to call DisposeAsync and not Dispose when the control reaches the end of the using block. When should you implement both IAsyncDisposable and IDisposable? Microsoft recommends that you implement both IAsyncDisposable and IDisposable interfaces in your code. You should not consider IAsyncDisposable as a replacement for the IDisposable interface. Instead, you should consider IAsyncDisposable to be just another way of implementing the dispose pattern. If you don’t implement the Dispose method, any code that doesn’t run in the async context will block on the DisposeAsync method so that the DisposeAsync method can be executed synchronously. Additionally, when you’re using IoC (inversion of control) containers and if your container has been disposed synchronously, a runtime exception might be thrown because the DisposeAsync method will never be called. As Microsoft states in the .NET documentation: It is typical when implementing the IAsyncDisposable interface that classes will also implement the IDisposable interface. A good implementation pattern of the IAsyncDisposable interface is to be prepared for either synchronous or asynchronous dispose. All of the guidance for implementing the dispose pattern also applies to the asynchronous implementation. Implement synchronous and asynchronous dispose in .NET The following code listing demonstrates how you can implement a synchronous and an asynchronous dispose pattern in your code: public class Example : IDisposable, IAsyncDisposable { private FileStream fileStream = new FileStream("D:test.txt", FileMode.Create); public void Dispose() { // Write code here to dispose resources synchronously fileStream.Dispose(); } public async ValueTask DisposeAsync() { // Write code here to dispose resources asynchronously await fileStream.DisposeAsync(); } } The System.IAsyncDisposable interface was released with C# 8.0. Similar to IDisposable, you should dispose IAsyncDisposable objects at the end of an HTTP request. You should call GC.SupressFinalize(this) in your Dispose or DisposeAsync method so that the garbage collector doesn’t need to call the destructor later. Related content news Microsoft unveils imaging APIs for Windows Copilot Runtime Generative AI-backed APIs will allow developers to build image super resolution, image segmentation, object erase, and OCR capabilities into Windows applications. By Paul Krill Nov 19, 2024 2 mins Generative AI APIs Development Libraries and Frameworks news Akka distributed computing platform adds Java SDK Akka enables development of applications that are primarily event-driven, deployable on Akka’s serverless platform or on AWS, Azure, or GCP cloud instances. By Paul Krill Nov 18, 2024 2 mins Java Scala Serverless Computing news Spin 3.0 supports polyglot development using Wasm components Fermyon’s open source framework for building server-side WebAssembly apps allows developers to compose apps from components created with different languages. By Paul Krill Nov 18, 2024 2 mins Microservices Serverless Computing Development Libraries and Frameworks how-to How to use DispatchProxy for AOP in .NET Core Take advantage of the DispatchProxy class in C# to implement aspect-oriented programming by creating proxies that dynamically intercept method calls. By Joydip Kanjilal Nov 14, 2024 7 mins Microsoft .NET C# Development Libraries and Frameworks Resources Videos