Imagine you want to write a method similar to the following one. It wraps a function returning a ValueTask<T>
with trivial performance monitoring 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 could simply duplicate the code and change just the parameter's type.
static async Task Measure<T>(Func<Task<T>> body) { ... }
The implementation would be absolutely identical. I am asking myself if it is possible to avoid this kind of code duplication when having to deal with ValueTask
and Task
. Up to now, I could not come up with a good solution. Any ideas?
According to official documentation: Generalized async return types
The
ValueTask
struct has a constructor with aTask
parameter so that you can construct aValueTask
from the return value of any existing async method:
That means you can write an overload that will wrap the body
and call only one method that will do the work
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With