All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.plugins.csharp.S5034.html Maven / Gradle / Ivy

There is a newer version: 10.2.0.105762
Show newest version

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:

  • Calling await multiple times on a ValueTask/ValueTask<TResult>. The wrapped object may have been reused by another operation. This differs from Task/Task<TResult>, on which you can await multiple times and always get the same result.
  • Calling await concurrently on a ValueTask/ValueTask<TResult>. The underlying object is not thread safe. What’s more, it has the same effect as awaiting multiple times a ValueTask/ValueTask<TResult>. This again differs from Task/Task<TResult>, which support concurrent await.
  • Using .Result or .GetAwaiter().GetResult() without checking if the operation is completed. IValueTaskSource/IValueTaskSource<TResult> implementations are not required to block until the operation completes. On the other hand, Task/Task<TResult> blocks the call until the task completes.

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:

  • Awaiting the instance multiple times.
  • Calling AsTask multiple times.
  • Using .Result or .GetAwaiter().GetResult() multiple times
  • Using .Result or .GetAwaiter().GetResult() when the operation has not yet completed
  • Using of these ways to consume the instance multiple times.

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

Standards





© 2015 - 2024 Weber Informatics LLC | Privacy Policy