ValueTask<TResult> was introduced in .NET Core 2.0 to optimize memory allocation when functions return their results synchronously.

ValueTask and ValueTask<TResult> should never be used in the following ways as it could result in a race condition:

It is recommended to use ValueTask / ValueTask<TResult> either by calling "await" on the function returning it, optionally calling ConfigureAwait(false) on it, or by calling .AsTask() on it.

This rule raises an issue when the following operations are performed on a ValueTask / ValueTask<TResult> instance:

Noncompliant Code Example

ValueTask<int> vt = SomeValueTaskReturningMethodAsync();
int result = await vt;
int result2 = await vt; // Noncompliant, variable is awaited multiple times

int value = SomeValueTaskReturningMethodAsync().GetAwaiter().GetResult(); // Noncompliant, uses GetAwaiter().GetResult() when it's not known to be done

Compliant Solution

int result = await SomeValueTaskReturningMethodAsync();

int result = await SomeValueTaskReturningMethodAsync().ConfigureAwait(false);

Task<int> t = SomeValueTaskReturningMethodAsync().AsTask();

Exceptions

This rule does not raise any issue when a ValueTask / ValueTask<TResult> is awaited multiple time in a loop.

See