Why is this an issue?

ValueTask<TResult> provides a value type that wraps a Task<TResult> and the corresponding TResult. It was introduced in .NET Core 2.0 to optimize memory allocation when functions return their results synchronously.

Using ValueTask and ValueTask<TResult> in the following ways is discouraged 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 unless it happens in a loop:

How to fix it

Code examples

Noncompliant code example

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

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

Compliant solution

ValueTask<int> vt = ComputeAsync();
int result = await vt;

int value = await ComputeAsync().AsTask();

Resources

Documentation