简体   繁体   中英

How to write a method that can handle Task and ValueTask?

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 a Task parameter so that you can construct a ValueTask 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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM