Home > Net >  How to release a ValueTask that wraps a sideeffect without using await?
How to release a ValueTask that wraps a sideeffect without using await?

Time:11-06

If I have a "resultless" ValueTask, (as in plain ValueTask, not a ValueTask<T>) that has completed synchronously such that valueTask.IsCompletedSuccessfully is true, 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.

CodePudding user response:

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.

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.

  • Related