Sdílet prostřednictvím


Task.FromResult může vrátit singleton

Task.FromResult<TResult>(TResult) nyní může vrátit instanci uloženou Task<TResult> v mezipaměti, nikoli vždy vytvořit novou instanci.

Staré chování

V předchozích verzích Task.FromResult<TResult>(TResult) by vždy přiděloval novou Task<TResult>, bez ohledu na typ T nebo výslednou hodnotu.

Nové chování

U některých T typů a některých výsledných hodnot Task.FromResult<TResult>(TResult) může být vrácen jeden objekt v mezipaměti, nikoli přidělení nového objektu. Například je pravděpodobné, že každé volání, které Task.FromResult(true) má vrátit stejný již dokončený Task<bool> objekt.

Zavedená verze

.NET 6

Typ zásadní změny

Tato změna může ovlivnit binární kompatibilitu.

Důvod změny

Mnoho vývojářů se očekávalo Task.FromResult<TResult>(TResult) , že se bude chovat podobně jako asynchronní metody, které už takové ukládání do mezipaměti provedlo. Vývojáři, kteří věděli o chování přidělení, často udržovali svou vlastní mezipaměť, aby se vyhnuli nákladům na výkon při přidělování těchto běžně používaných hodnot. Příklad:

private static readonly Task<bool> s_trueTask = Task.FromResult(true);

Tyto vlastní mezipaměti se už pro hodnoty, jako Boolean jsou a malé Int32 hodnoty, nevyžadují.

Pokud nepoužíváte rovnost odkazů ke kontrole, jestli je jedna Task instance stejná jako jiná Task instance, nemělo by to mít vliv na tuto změnu. Pokud používáte takovou rovnost odkazů a potřebujete pokračovat v této kontrole, zaručte vždy jedinečnou Task<TResult> instanci pomocí následujícího kódu:

private static Task<T> NewInstanceFromResult<T>(T result)
{
    var tcs = new TaskCompletionSource<T>();
    tcs.TrySetResult(result);
    return tcs.Task;
}

Poznámka:

Tento model je mnohem méně efektivní než jen použití Task.FromResult(result)a měl by se vyhnout, pokud ho opravdu nepotřebujete.

Ovlivněná rozhraní API