Qual a diferença entre usar e aguardar o uso? E como posso decidir qual usar?

21

Percebi que, em alguns casos, o Visual Studio recomenda fazer isso

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

em vez disso

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

Qual é a diferença entre usinge await using?

Como devo decidir qual usar?

Justin Lessard
fonte
3
Parece que você só pode usar await usingcom um IAsyncDisposablee você só pode usar usingcom um, uma IDisposablevez que nenhum herda do outro. O único momento em que você pode usar é se a classe concreta implementa as duas coisas e depende se você está escrevendo código assíncrono ou não.
2141919

Respostas:

31

Sincronização clássica usando

O uso clássico chama o Dispose()método de um objeto que implementa a IDisposableinterface.

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

É equivalente a

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

Novo assíncrono aguarda o uso

Os novos aguardam o uso de chamadas e aguardam o DisposeAsync()método de um objeto implementando a IAsyncDisposableinterface.

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

É equivalente a

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

A interface IAsyncDisposable foi adicionada em .NET Core 3.0e .NET Standard 2.1.

No .NET, as classes que possuem recursos não gerenciados geralmente implementam a interface IDisposable para fornecer um mecanismo para liberar recursos não gerenciados de forma síncrona. No entanto, em alguns casos, eles precisam fornecer um mecanismo assíncrono para liberar recursos não gerenciados, além do (ou em vez de) o síncrono . O fornecimento desse mecanismo permite que o consumidor realize operações de descarte que consomem muitos recursos sem bloquear o encadeamento principal de um aplicativo GUI por um longo tempo.

O método IAsyncDisposable.DisposeAsync dessa interface retorna um ValueTask que representa a operação de descarte assíncrona. Classes que possuem recursos não gerenciados implementam esse método, e o consumidor dessas classes chama esse método em um objeto quando ele não é mais necessário.

Justin Lessard
fonte