What is ValueTask in C#: Explanation and Usage
ValueTask in C# is a lightweight alternative to Task for asynchronous operations that may complete synchronously or asynchronously. It helps reduce memory allocations by avoiding creating a new Task object when the result is already available.How It Works
Imagine you ask a friend for a quick answer. Sometimes they know it immediately and tell you right away. Other times, they need to check and get back later. ValueTask works like this friend: it can hold a result ready now or promise to deliver it later.
Normally, asynchronous methods return a Task, which always creates an object even if the result is ready immediately. ValueTask can either wrap a Task or directly hold the result value, saving memory and improving speed when the result is already known.
This makes ValueTask useful when you want to avoid the cost of creating many Task objects in high-performance scenarios.
Example
This example shows a method that returns a ValueTask<int>. It returns a completed result immediately if the input is zero; otherwise, it simulates an asynchronous delay.
using System; using System.Threading.Tasks; class Program { static async ValueTask<int> GetNumberAsync(int input) { if (input == 0) { // Return synchronously completed result return 42; } else { // Simulate async work await Task.Delay(100); return input * 2; } } static async Task Main() { int result1 = await GetNumberAsync(0); Console.WriteLine($"Result when input is 0: {result1}"); int result2 = await GetNumberAsync(5); Console.WriteLine($"Result when input is 5: {result2}"); } }
When to Use
Use ValueTask when your asynchronous method often completes synchronously and you want to avoid the overhead of creating a Task object every time. This is common in high-performance or low-latency applications like networking, caching, or I/O operations.
However, if your method mostly completes asynchronously or you don't care about small performance gains, using Task is simpler and safer.
Remember, ValueTask has some usage rules: it should only be awaited once and not stored or combined with other tasks, so use it only when you understand these constraints.
Key Points
- ValueTask can hold a result immediately or a
Taskfor later completion. - It reduces memory allocations when results are often ready synchronously.
- Use it in performance-critical async methods that complete quickly.
- Follow usage rules: await once, avoid storing or multiple awaits.
- For most cases,
Taskremains simpler and preferred.
Key Takeaways
ValueTask reduces overhead by avoiding unnecessary Task allocations when results are ready immediately.ValueTask in high-performance async methods that often complete synchronously.ValueTask only once and avoid storing it for later reuse.Task is simpler and safer to use.ValueTask helps optimize memory and speed in critical scenarios.