If I have a "resultless" ValueTask
, (as in plain ValueTask
, not a ValueTask<T>
) that has completed synchronously such that valueTask.IsCompletedSuccessfully
is true. The ValueTask
has not been await
ed. How do I tell to the runtime that I'm done with the ValueTask
, and that it can be reused if it happens to be backed by a IValueTaskSource
?
ValueTask<T>
has a Result
property and accessing it (presumably) marks the ValueTask<T>
as consumed, but a plain ValueTask
has no Result
.
You can notify the underlying IValueTaskSource
object that the ValueTask
has been consumed, by calling the .GetAwaiter()
.GetResult()
method on the task:
if (valueTask.IsCompletedSuccessfully)
{
valueTask.GetAwaiter().GetResult();
}
This call does not cause any allocation. The ValueTaskAwaiter
is a struct.
The effect that the .GetAwaiter().GetResult()
has on consuming the ValueTask
is not documented. It can only be derived by studying the source code of the relevant types (ValueTask
, ValueTaskAwaiter
, ManualResetValueTaskSourceCore
).
Caution: Calling the .GetAwaiter().GetResult()
before the task is completed, is not a valid operation for a ValueTask
. It is also forbidden to call the .GetAwaiter().GetResult()
more than once, or in tandem with any other consuming operation like await
or AsTask
. These restrictions are documented in the Remarks section of the ValueTask
struct.