DEV Community

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

Posted on

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

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

Top comments (2)

Collapse
 
mkefclio profile image
mkefclio

Great article!

Collapse
 
stevsharp profile image
Spyros Ponaris

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