Using the following methods as an example:
public async ValueTask<int> MyMethod() {
return await GetMyIntegerWithTask();
}
public async Task<int> GetMyIntegerWithTask() {
if (/*in hot path*/) {
return await SynchronousMethodThatUsesTask();
}
return await AsynchronousMethodThatUsesTask();
}
public Task<int> SynchronousMethodThatUsesTask() {
int value = new Random().Next();
return Task.FromResult(value);
}
public async Task<int> AsynchronousMethodThatUsesTask() {
//some asynchronous calculation
}
Does using ValueTask
as the return type of MyMethod
still have the advantages associated with ValueTask
because I expect that most of the time my code will execute synchronously (even though the synchronous method I'm depending on returns Task
rather than ValueTask
)?
The performance benefits of
ValueTask
are minor, unless you are calling this very often. That said, yes,ValueTask
will at the very least avoid aTask
allocation, and in the synchronous case also avoids boxing the state machine struct onto the heap.It would be better if both
GetMyIntegerWithTask
andSynchronousMethodThatUsesTask
also useValueTask<int>
, but even without thatMyMethod
can useValueTask<int>
to avoid some allocations, at least.