¿Cuál es la diferencia entre usar y esperar usar? ¿Y cómo puedo decidir cuál usar?

21

Me di cuenta de que, en algún caso, Visual Studio recomienda hacer esto

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

en lugar de esto

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

¿Cuál es la diferencia entre usingy await using?

¿Cómo debo decidir cuál usar?

Justin Lessard
fuente
3
Parece que solo se puede usar await usingcon a IAsyncDisposabley solo se puede usar usingcon a IDisposableya que ninguno hereda del otro. El único momento que puede usar es si la clase concreta implementa ambos y luego depende de si está escribiendo código asincrónico o no.
juharr

Respuestas:

31

Sincronización clásica usando

El uso clásico llama al Dispose()método de un objeto que implementa la IDisposableinterfaz.

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

Es equivalente a

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

Nueva asíncrona aguarda utilizando

El nuevo espera usando llamadas y espera el DisposeAsync()método de un objeto que implementa la IAsyncDisposableinterfaz.

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

Es equivalente a

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

La interfaz IAsyncDisposable se agregó en .NET Core 3.0y .NET Standard 2.1.

En .NET, las clases que poseen recursos no administrados generalmente implementan la interfaz IDisposable para proporcionar un mecanismo para liberar recursos no administrados sincrónicamente. Sin embargo, en algunos casos necesitan proporcionar un mecanismo asíncrono para liberar recursos no administrados además de (o en lugar de) el sincronizado . Proporcionar un mecanismo de este tipo permite al consumidor realizar operaciones de eliminación intensivas en recursos sin bloquear el hilo principal de una aplicación GUI durante mucho tiempo.

El método IAsyncDisposable.DisposeAsync de esta interfaz devuelve una ValueTask que representa la operación de eliminación asíncrona. Las clases que poseen recursos no administrados implementan este método, y el consumidor de estas clases llama a este método en un objeto cuando ya no es necesario.

Justin Lessard
fuente