How do I write a method that can handle Task and ValueTask?
Imagine that you want to write a method similar to the following. It wraps a function that returns ValueTask<T>
trivial performance control code:
static async Task Measure<T>(Func<ValueTask<T>> body)
{
Console.WriteLine($"Starting perf test");
var sw = Stopwatch.StartNew();
await body();
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
My question is, is there a way to write this function once so that it can receive Func<ValueTask<T>>
and Func<Task<T>>
?
Of course, you can just duplicate the code and only change the type of the parameter.
static async Task Measure<T>(Func<Task<T>> body) { ... }
The implementation will be exactly the same. I ask myself if this kind of code duplication can be avoided when dealing with ValueTask
and Task
. Until now, I couldn't find a good solution. Any ideas?
source to share
According to the official documentation: Generic async return types
The struct
ValueTask
has a parameterized constructorTask
, so you can buildValueTask
from the return value of any existing async method:
This means that you can write an overload that will wrap body
and call only one method that will do the job
static Task Measure<T>(Func<Task<T>> body)
{
var wrapped = () => new ValueTask<T>( body() );
return Measure( wrapped );
}
static async Task Measure<T>(Func<ValueTask<T>> body)
{
Console.WriteLine($"Starting perf test");
var sw = Stopwatch.StartNew();
await body();
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
source to share