What is ValueTask? Why ValueTask Could Be Your Key to Faster Async Code ?
Spyros Ponaris

Spyros Ponaris @stevsharp

About: Tech Lead | Senior Software Engineer | .NET Enthusiast (BSc, MSc, MCP, MCSD) Contact Information: https://www.linkedin.com/in/spyros-ponaris-913a6937/

Location:
Athens
Joined:
Dec 23, 2019

What is ValueTask? Why ValueTask Could Be Your Key to Faster Async Code ?

Publish Date: Jan 20
3 2

ValueTask is a structure introduced in .NET for scenarios requiring micro-optimizations in asynchronous programming. It provides an alternative to Task with better performance for specific use cases, such as when the result of an asynchronous operation is already available or can be synchronously produced.

Key Characteristics:

  1. ValueTask can be used for both asynchronous and synchronous results, while Task is inherently asynchronous.
  2. Unlike Task, which always allocates a heap object, ***ValueTask* **avoids allocation when the result is immediately available.
  3. It’s particularly useful in high-performance scenarios to reduce unnecessary allocations.

Common Use Cases:

  1. Operations that are frequently completed synchronously, where allocation overhead from Task would be significant.
  2. APIs implementing IAsyncEnumerable, which often return ValueTask for efficiency.

Precautions When Using ValueTask
Avoid Awaiting the Same Instance Multiple Times

  • Unlike Task, a ValueTask is not reusable. Awaiting it multiple times can lead to undefined behavior.
ValueTask<int> task = SomeMethodAsync();
await task; // Valid
await task; // Undefined behavior
Enter fullscreen mode Exit fullscreen mode
  • Avoid .GetAwaiter().GetResult() If the Operation Isn’t Completed
  • Avoid Using the Instance After It’s Awaited
    Once awaited, the state of ValueTask can no longer be relied upon, unlike Task, which can be awaited multiple times.

  • Avoiding excessive bouncing
    For methods that are called many times in a loop, you can avoid the cost of
    repeatedly bouncing to a UI message loop by calling ConfigureAwait. This forces
    a task not to bounce continuations to the synchronization context, cutting the
    overhead closer to the cost of a context switch

Image description

When to Use ValueTask?
Use Task for the majority of asynchronous methods. It is simpler, more versatile, and less error-prone.

Use ValueTask when:

  • You need to eliminate allocations in highly optimized scenarios.
  • The operation frequently completes synchronously.
  • You understand the constraints and risks associated with ValueTask.

GitHub code:
https://github.com/stevsharp/ValueTaskVsTask

Microsoft Documentation
ValueTask Structure:

https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.valuetask?view=net-7.0
Provides an in-depth overview of the ValueTask struct, its properties, and when to use it.
Performance Considerations:

https://learn.microsoft.com/en-us/dotnet/csharp/asynchronous-programming/async-scenarios#valuetask
Discusses the scenarios where ValueTask can improve performance and best practices.
IAsyncEnumerable and ValueTask:

Books
Concurrency in C# Cookbook by Stephen Cleary:
https://www.amazon.com/dp/B0D3LBH7XK/ref=syn_sd_onsite_desktop_0?ie=UTF8&psc=1&pf_rd_p=d77a94d7-221a-4129-af34-3c16ad136bb7&pf_rd_r=G7CDS7WJY28HD4V75DSS&pd_rd_wg=1B1RT&pd_rd_w=CV9FH&pd_rd_r=061c7653-1306-4284-bac1-291bdf9f8c8f&aref=40Jzhu2vTB

Contains practical examples and explanations on using ValueTask effectively in asynchronous programming.

Pro .NET Memory Management by Konrad Kokosa:
https://www.amazon.com/Pro-NET-Memory-Management-Performance/dp/148424026X

Comments 2 total

  • mkefclio
    mkefclioJan 20, 2025

    Great article!

    • Spyros Ponaris
      Spyros PonarisJan 21, 2025

      Thanks a lot! I’m happy you liked it. If you have any thoughts or feedback, I’d love to hear them.

Add comment