Home / Forums / When to use ValueTask<T> vs Task<T> in Performance-Critical C# APIs

UnreliableCode Community

Developer Research, Reverse Engineering & Coding Community

Tutorial

When to use ValueTask<T> vs Task<T> in Performance-Critical C# APIs

AsyncMaster
Concurrency Geek
MEMBER
Rep: 72
Join Date: Jul 2020
Posts: 13
Thanks: 83
1y ago · Nov 5, 2024 4:45 PM
#1
A common question for intermediate C# developers: when should you return
CODE
ValueTask<T>
instead of
CODE
Task<T>
?

The Rule:
- Use Task<T> when the method is expected to complete asynchronously >80% of the time (e.g. database network queries, disk file I/O).
- Use ValueTask<T> when the method completes **synchronously in the majority of cases** (e.g. memory cache hits, pre-buffered socket reads).

CSHARP
public class CacheService
{
    private readonly ConcurrentDictionary<string, byte[]> _memoryCache = new();

    public ValueTask<byte[]> GetCachedDataAsync(string key)
    {
        // Fast path: In-memory cache hit (Zero heap allocation!)
        if (_memoryCache.TryGetValue(key, out byte[]? data))
        {
            return new ValueTask<byte[]>(data);
        }

        // Slow path: Fallback to async disk/network load
        return new ValueTask<byte[]>(LoadFromRemoteAsync(key));
    }

    private async Task<byte[]> LoadFromRemoteAsync(string key) { ... }
}


Crucial Rule with ValueTask: Never await a
CODE
ValueTask
twice, and never call
CODE
.Result
before awaiting, because the underlying value struct may be pooled and recycled!
AsyncMaster · Concurrency Geek
Task Parallel Library (TPL), async/await internals, and lock...
The following users thanked AsyncMaster for this post:
CSharpNinja
Senior .NET Developer
VIP
Rep: 329
Join Date: Jan 2020
Posts: 16
Thanks: 75
1y ago · Nov 5, 2024 7:55 PM
#2
The single-await restriction on
CODE
ValueTask
is vital to remember. If you need to store the task or await it multiple times across branches, convert it with
CODE
.AsTask()
!
CSharpNinja · Senior .NET Developer
C# enthusiast, building distributed backend services and hig...
DevDan
.NET Core & Cloud
MEMBER
Rep: 324
Join Date: Feb 2021
Posts: 16
Thanks: 65
1y ago · Nov 6, 2024 8:55 PM
#3
CODE
ValueTask
on our caching layer reduced task object allocations by over 40 million objects per hour during peak traffic on our service!
DevDan · .NET Core & Cloud
Writing clean C# code and microservices since .NET Core 2.1....