В чем разница между использованием и ожиданием использования? И как я могу решить, какой использовать?

21

Я заметил, что в некоторых случаях Visual Studio рекомендует сделать это

await using var disposable = new Disposable();
// Do something

вместо этого

using var disposable = new Disposable();
// Do something

В чем разница между usingи await using?

Как я должен решить, какой использовать?

Джастин Лессард
источник
3
Похоже, вы можете использовать только await usingс, IAsyncDisposableи вы можете использовать только usingс, IDisposableтак как ни один не наследует от другого. Единственный раз, когда вы можете использовать любой из них, это если конкретный класс реализует оба, и тогда это зависит от того, пишете ли вы асинхронный код или нет.
19

Ответы:

31

Классическая синхронизация с использованием

Классическое использование вызывает Dispose()метод объекта, реализующего IDisposableинтерфейс.

using var disposable = new Disposable();
// Do Something...

Эквивалентно

IDisposable disposable = new Disposable();
try
{
    // Do Something...
}
finally
{
    disposable.Dispose();
}

Новая асинхронная версия ожидает использования

Новые ожидают использования вызовов и ожидают DisposeAsync()метода объекта, реализующего IAsyncDisposableинтерфейс.

await using var disposable = new AsyncDisposable();
// Do Something...

Эквивалентно

IAsyncDisposable disposable = new AsyncDisposable();
try
{
    // Do Something...
}
finally
{
    await disposable.DisposeAsync();
}

IAsyncDisposable интерфейс был добавлен в .NET Core 3.0и .NET Standard 2.1.

В .NET классы, владеющие неуправляемыми ресурсами, обычно реализуют интерфейс IDisposable, чтобы обеспечить механизм для синхронного высвобождения неуправляемых ресурсов. Однако в некоторых случаях им необходимо предоставить асинхронный механизм для освобождения неуправляемых ресурсов в дополнение (или вместо) к синхронному . Предоставление такого механизма позволяет потребителю выполнять ресурсоемкие операции по удалению без длительной блокировки основного потока приложения с графическим интерфейсом.

Метод IAsyncDisposable.DisposeAsync этого интерфейса возвращает значение ValueTask , представляющее асинхронную операцию удаления. Классы, которые владеют неуправляемыми ресурсами, реализуют этот метод, и потребитель этих классов вызывает этот метод для объекта, когда он больше не нужен.

Джастин Лессард
источник