Developer knowledge network · moderated exchange

Супольнасць UnreliableCode

Супольнасць распрацоўшчыкаў даследаванняў, зваротнага праектавання і кадавання

Knowledge indexжыць
4Categories
919Threads
2.8KПаведамленні
Discussion

ValueTask<T> vs Task<T>: When to use ValueTask for zero-allocation performance [StackOverflow Architecture Guide]

dotnet_runtime_architect
.NET Core Specialist
MEMBER
прадстаўнік: 103
Дата далучэння: Apr 2018
Паведамленні: 40
Дзякуй: 24
3 тыдняў таму · Jul 31, 2026 2:00 PM
#1

Why returning Task<T> creates heap allocations even for synchronously completed operations:

Task<T> is a class on the managed heap. If a cached method completes synchronously 90% of the time, creating a new Task<T> on every call generates useless GC Gen-0 garbage.

When to use ValueTask<T>:

CSHARP
public ValueTask<int> GetCachedCountAsync()
{
    if (_cache.TryGetValue("count", out int val))
        return new ValueTask<int>(val); // 0 Heap Allocations! Wrapped in a stack struct!
        
    return new ValueTask<int>(FetchCountFromDatabaseAsync());
}

Golden Rule: Use ValueTask<T> when the method completes synchronously in hot paths (e.g. cache hits, buffered stream reads).

csharp_async_master
Async & Task Expert
MEMBER
прадстаўнік: 57
Дата далучэння: Mar 2019
Паведамленні: 18
Дзякуй: 40
3 тыдняў таму · Jul 31, 2026 8:38 PM
#2

Important caveat: A ValueTask can only be awaited once! Multiple awaits or calling .Result on a pending ValueTask can lead to race conditions with pooled task sources.

profiler_pat
Performance Hunter
MEMBER
прадстаўнік: 146
Дата далучэння: Aug 2019
Паведамленні: 33
Дзякуй: 31
3 тыдняў таму · Aug 1, 2026 10:02 AM
#3

Replacing Task<int> with ValueTask<int> on our in-memory cache layer eliminated 4.2GB of Gen-0 garbage per hour.