Quelle est la différence entre l'utilisation et l'attente de l'utilisation? Et comment puis-je décider lequel utiliser?

21

J'ai remarqué que dans certains cas, Visual Studio recommande de le faire

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

au lieu de cela

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

Quelle est la difference entre usinget await using?

Comment dois-je décider lequel utiliser?

Justin Lessard
la source
3
Il semble que vous ne puissiez l'utiliser await usingqu'avec un IAsyncDisposableet que vous ne pouvez l'utiliser usingqu'avec un IDisposablecar aucun n'hérite de l'autre. Le seul moment où vous pouvez utiliser l'un ou l'autre est si la classe concrète implémente les deux et cela dépend si vous écrivez du code asynchrone ou non.
juharr

Réponses:

31

Synchronisation classique à l'aide

L'utilisation classique appelle la Dispose()méthode d'un objet implémentant l' IDisposableinterface.

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

Est équivalent à

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

Nouvelle asynchrone en attente d'utilisation

Les nouveaux attendent d'utiliser des appels et attendent la DisposeAsync()méthode d'un objet implémentant l' IAsyncDisposableinterface.

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

Est équivalent à

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

L' interface IAsyncDisposable a été ajoutée dans .NET Core 3.0et .NET Standard 2.1.

Dans .NET, les classes qui possèdent des ressources non gérées implémentent généralement l' interface IDisposable pour fournir un mécanisme de libération synchrone des ressources non gérées. Cependant, dans certains cas, ils doivent fournir un mécanisme asynchrone pour libérer des ressources non gérées en plus (ou à la place) de la ressource synchrone . La fourniture d'un tel mécanisme permet au consommateur d'effectuer des opérations d'élimination à forte intensité de ressources sans bloquer le thread principal d'une application GUI pendant une longue période.

La méthode IAsyncDisposable.DisposeAsync de cette interface renvoie une ValueTask qui représente l'opération de suppression asynchrone. Les classes qui possèdent des ressources non managées implémentent cette méthode et le consommateur de ces classes appelle cette méthode sur un objet lorsqu'il n'est plus nécessaire.

Justin Lessard
la source