[StructLayout(LayoutKind.Auto)]
public readonly struct ValueTask : IEquatable<ValueTask>
{
- /// <summary>A task canceled using `new CancellationToken(true)`.</summary>
- private static readonly Task s_canceledTask = Task.FromCanceled(new CancellationToken(canceled: true));
+ /// <summary>A task canceled using `new CancellationToken(true)`. Lazily created only when first needed.</summary>
+ private static volatile Task? s_canceledTask;
/// <summary>null if representing a successful synchronous completion, otherwise a <see cref="Task"/> or a <see cref="IValueTaskSource"/>.</summary>
internal readonly object? _obj;
return task;
}
- return s_canceledTask;
+ // Benign race condition to initialize cached task, as identity doesn't matter.
+ return s_canceledTask ??= Task.FromCanceled(new CancellationToken(canceled: true));
}
else
{
public readonly struct ValueTask<TResult> : IEquatable<ValueTask<TResult>>
{
/// <summary>A task canceled using `new CancellationToken(true)`. Lazily created only when first needed.</summary>
- private static Task<TResult>? s_canceledTask;
+ private static volatile Task<TResult>? s_canceledTask;
/// <summary>null if <see cref="_result"/> has the result, otherwise a <see cref="Task{TResult}"/> or a <see cref="IValueTaskSource{TResult}"/>.</summary>
internal readonly object? _obj;
/// <summary>The result to be used if the operation completed successfully synchronously.</summary>
return task;
}
- Task<TResult>? canceledTask = s_canceledTask;
- if (canceledTask == null)
- {
- // Benign race condition to initialize cached task, as identity doesn't matter.
- s_canceledTask = canceledTask = Task.FromCanceled<TResult>(new CancellationToken(true));
- }
- return canceledTask;
+ // Benign race condition to initialize cached task, as identity doesn't matter.
+ return s_canceledTask ??= Task.FromCanceled<TResult>(new CancellationToken(true));
}
else
{