CA2012: Správné použití ValueTasks

Vlastnost Hodnota
ID pravidla CA2012
Název Správně používat ValueTasks
Kategorie Spolehlivost
Oprava, která může být destruktivní nebo nedestruktivní Nezlomitelný
Povoleno ve výchozím nastavení v .NET 10 Jako návrh
Příslušné jazyky C# a Visual Basic

Příčina

ValueTask Instance vrácená z volání člena se používá způsobem, který může vést k výjimkám, poškození nebo nízkému výkonu.

Popis pravidla

ValueTask Instance vrácené z volání členů jsou určeny k přímému čekání. Pokusy o opakované využití objektu ValueTask nebo o přímý přístup k jeho výsledku předtím, než je znám jeho dokončený stav, mohou vést k výjimce nebo k poškození. Ignorování objektu ValueTask pravděpodobně značí funkční chybu a může snížit výkon.

Jak opravit porušení

Obecně platí, že hodnoty ValueTasks by měly být přímo očekávány místo zahození nebo uložení do jiných umístění, jako jsou místní proměnné nebo pole.

Kdy potlačit upozornění

U ValueTask objektů vrácených z volání libovolných členů musí volající předpokládat, že ValueTask musí být využito (například očekáváno) jednou a pouze jednou. Pokud však vývojář také ovládá člena, který je volán, a má úplnou znalost jeho implementace, může vědět, že je bezpečné potlačit upozornění, například pokud vrácení ValueTask vždy zahrnuje Task objekt.

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;

        // ...
    }
}

Potlačení upozornění

Pokud chcete pouze potlačit jedno porušení, přidejte do zdrojového souboru direktivy preprocesoru, abyste pravidlo zakázali a znovu povolili.

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

Pokud chcete pravidlo pro soubor, složku nebo projekt zakázat, nastavte jeho závažnost v none konfiguračním souboru.

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

Další informace naleznete v tématu Jak potlačit upozornění analýzy kódu.

Viz také