Jaka jest różnica między używaniem a oczekiwaniem na używanie? I jak mogę zdecydować, którego użyć?

21

Zauważyłem, że w niektórych przypadkach Visual Studio zaleca to zrobić

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

zamiast tego

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

Jaka jest różnica między usingi await using?

Jak zdecydować, którego użyć?

Justin Lessard
źródło
3
Wygląda na to, że możesz używać tylko await usingz a IAsyncDisposablei możesz używać tylko usingz, IDisposableponieważ żadne z nich nie dziedziczy po drugim. Można użyć tylko jednego z nich, jeśli konkretna klasa implementuje oba, a następnie zależy to od tego, czy piszesz kod asynchroniczny, czy nie.
juharr

Odpowiedzi:

31

Klasyczna synchronizacja przy użyciu

Klasyczne użycie wywołuje Dispose()metodę obiektu implementującego IDisposableinterfejs.

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

Jest równa

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

Nowy async oczekuje na użycie

Nowe czekają na wywołania i oczekują na DisposeAsync()metodę obiektu implementującego IAsyncDisposableinterfejs.

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

Jest równa

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

IAsyncDisposable Interfejs dodano .NET Core 3.0i .NET Standard 2.1.

W .NET klasy posiadające niezarządzane zasoby zwykle implementują interfejs IDisposable , aby zapewnić mechanizm synchronicznego zwalniania niezarządzanych zasobów. Jednak w niektórych przypadkach muszą zapewnić mechanizm asynchroniczny do zwalniania niezarządzanych zasobów oprócz (lub zamiast) synchronicznego . Zapewnienie takiego mechanizmu umożliwia konsumentowi wykonywanie operacji usuwania wymagających dużej ilości zasobów bez blokowania głównego wątku aplikacji GUI przez długi czas.

Metoda IAsyncDisposable.DisposeAsync tego interfejsu zwraca wartość ValueTask, która reprezentuje asynchroniczną operację usuwania. Klasy posiadające niezarządzane zasoby implementują tę metodę, a konsument tych klas wywołuje tę metodę na obiekcie, gdy nie jest już potrzebny.

Justin Lessard
źródło