IAsyncDisposable
Интерфейс
IDisposable существует с .NET Framework 1.0 и даёт нам возможность освобождать занятые ресурсы. using (var disposable = new Disposable()) { … }
У IDisposable есть недостаток, который стал более очевидным с появлением Task. Освобождение ресурсов происходит синхронно и может блокировать потоки. Хуже того, неправильная утилизация асинхронного ресурса может привести к взаимным блокировкам.IAsyncDisposable
В .NET Core 3 появился интерфейс
IAsyncDisposable, который позволяет освобождать асинхронные ресурсы в методе DisposeAsync, возвращающем ValueTask:public interface IAsyncDisposable {
ValueTask DisposeAsync();
}
Заметьте, что IDisposable и IAsyncDisposable могут быть реализованы независимо друг от друга. Скорее всего, IAsyncDisposable не реализует IDisposable, потому что создатели не захотели создавать у разработчиков ложное впечатление, что по умолчанию во всех случаях есть синхронный вариант.Использование
Вот простой пример использования новой конструкции
await using с IAsyncDisposable. Сначала напишем класс, реализующий интерфейс:public class HotGarbage : IAsyncDisposable {
public async ValueTask DisposeAsync() {
Console.WriteLine("Чем так пахнет?");
await Task.Delay(TimeSpan.FromSeconds(3));
Console.WriteLine("Выкидываем мусор");
}
public void Look() => Console.WriteLine("Хмм...");
}
Надо заметить, что раз класс реализует IAsyncDisposable, то, вероятно, он имеет зависимости, требующие асинхронного удаления. Использование:static async Task Main(string[] args) {
async Task Run() {
await using var hotGarbage = new HotGarbage();
hotGarbage.Look();
}
await Run();
}
Мы используем локальную функцию внутри метода Main. Ключевые слова await using полезны, чтобы уменьшить количество скобок в коде и снизить вероятность ошибки при рефакторинге. Запустив код, мы видим результаты нашего асинхронного удаления:Хмм...Итого
Чем так пахнет?
Выкидываем мусор
Интерфейс
IAsyncDisposable должен упростить написание библиотек, которые имеют дело с операциями ввода-вывода. Авторы библиотек доступа к базам данных, обработки изображений и интернет-протоколов должны иметь возможность изящно избавляться от управляемых ресурсов, не опасаясь взаимных блокировок. Мы, как потребители библиотек, получаем приятный синтаксический сахар в виде конструкции await using, что ещё больше упрощает код.Источник: https://khalidabuhakmeh.com/iasyncdisposable-dispose-resources-asynchronously