Search code examples
c#asynchronousasync-awaitvaluetask

Will ValueTask still be beneficial if it depends on a method that returns Task?


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)?


Solution

  • 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 a Task allocation, and in the synchronous case also avoids boxing the state machine struct onto the heap.

    It would be better if both GetMyIntegerWithTask and SynchronousMethodThatUsesTask also use ValueTask<int>, but even without that MyMethod can use ValueTask<int> to avoid some allocations, at least.