Udostępnij za pośrednictwem


CA2012: Poprawnie używaj ValueTasks

Właściwości Wartość
Identyfikator reguły CA2012
Tytuł Poprawnie używaj ValueTask
Kategoria Niezawodność
Poprawka łamiąca lub nienaruszająca Niezgodność
Domyślnie włączone na platformie .NET 10 Jako sugestia
Zastosowane języki C# i Visual Basic

Przyczyna

Wystąpienie ValueTask zwrócone z wywołania członka jest używane w sposób, który może prowadzić do wyjątków, uszkodzenia lub niskiej wydajności.

Opis reguły

ValueTask wystąpienia zwracane z wywołań składowych mają być bezpośrednio oczekiwane. Próby wielokrotnego korzystania z ValueTask lub bezpośredniego dostępu do jego wyniku przed jego ukończeniem mogą prowadzić do wyjątku lub uszkodzenia systemu. Ignorowanie takiego ValueTask prawdopodobnie wskazuje na błąd funkcjonalny i może obniżyć wydajność.

Jak naprawić naruszenia

Ogólnie rzecz biorąc, funkcja ValueTasks powinna być bezpośrednio oczekiwana, a nie odrzucana lub przechowywana w innych lokalizacjach, takich jak zmienne lokalne lub pola.

Kiedy pomijać ostrzeżenia

W przypadku ValueTask obiektów zwracanych z dowolnych wywołań składowych obiekt wywołujący musi przyjąć, że ValueTask element musi być używany (na przykład oczekiwany) raz i tylko raz. Jeśli jednak deweloper kontroluje również wywoływany element i ma pełną wiedzę na temat jego implementacji, deweloper może wiedzieć, że można bezpiecznie pominąć ostrzeżenie, na przykład jeśli zwracany ValueTask element zawsze jest opakowaniem obiektu Task.

Example

public class NumberValueTask
{
    public async ValueTask<int> GetNumberAsync()
    {
        await Task.Delay(100);
        return 123;
    }

    public async Task UseValueTaskIncorrectlyAsync()
    {
        // This code violates the rule,
        // because ValueTask is awaited multiple times
        ValueTask<int> numberValueTask = GetNumberAsync();

        int first = await numberValueTask;
        int second = await numberValueTask; // <- illegal reuse

        // ...
    }

    // This code satisfies the rule.
    public async Task UseValueTaskCorrectlyAsync()
    {
        int first = await GetNumberAsync();
        int second = await GetNumberAsync();

        // ..
    }

    public async Task UseValueTaskAsTaskAsync()
    {
        ValueTask<int> numberValueTask = GetNumberAsync();

        Task<int> numberTask = numberValueTask.AsTask();

        int first = await numberTask;
        int second = await numberTask;

        // ...
    }
}

Pomijanie ostrzeżenia

Jeśli chcesz po prostu pominąć pojedyncze naruszenie, dodaj dyrektywy preprocesora do pliku źródłowego, aby wyłączyć, a następnie ponownie włączyć regułę.

#pragma warning disable CA2012
// The code that's violating the rule is on this line.
#pragma warning restore CA2012

Aby wyłączyć regułę dla pliku, folderu lub projektu, ustaw jego ważność na none w pliku konfiguracji.

[*.{cs,vb}]
dotnet_diagnostic.CA2012.severity = none

Aby uzyskać więcej informacji, zobacz Jak pominąć ostrzeżenia dotyczące analizy kodu.

Zobacz też