TGStat
TGStat
Type to search
Advanced channel search
  • flag English
    Site language
    flag Russian flag English flag Uzbek
  • Sign In
  • Catalog
    Channels and groups catalog Regional compilations Thematic compilations Платные каналы Search for channels
    Add a channel/group
  • Ratings
    Rating of channels Rating of groups Posts rating
    Ratings of brands and people
  • Analytics
  • Search by posts
  • Telegram monitoring
  • Promotion
    Advertising through Yandex Business Advertising in channels through TGStat Agency Advertising on TGStat.ru website
НеСерьезный шарпист

28 Jun 2025, 18:32

Open in Telegram Share Report

Столкнулся с тем, что, как выяснилось, не всем очевидно для чего нужен ValueTask и когда его стоит использовать. Что ж 🤨

ValueTask - это структура-обертка, которую стоит использовать вместо Task в тех случаях, когда результат может быть получен синхронно, что позволит избежать лишней аллокации объекта Task в куче.
Однако ValueTask не должен использоваться в качестве возвращаемого значения во всех под ряд методах, т.к. это может привести к проблемам с производительностью.

НЕ используйте ValueTask, если выполняются хотябы одно условие:
❌ Метод всегда выполняется асинхронно.
❌ Метод объявлен как async (всегда будет все равно создаваться AsyncStateMachine, поэтому ValueTask будет бессмысленен).
❌ Метод редко вызывается — выигрыш от избежания аллокации Task незначителен.
❌ Метод явялется публичным API библиотеки.
❌ Используется .Result, .GetAwaiter().GetResult(), .AsTask() или повторный await.
public async ValueTask GetUserAsync(Guid id)
{
var result = await dbContext.Users.FirstOrDefaultAsync(u => u.Id == id);

return result;
}

Используйте ValueTask, если выполняются все условия:
✅ Результат может быть получен синхронно (например, из кэша).
✅ Метод не использует async/await.
✅ Метод вызывается часто и критичен по производительности, где аллокации Task значимы.
✅ Нет необходимости повторно ожидать ValueTask.
✅ Вызов Task-версии метода означает ненужную аллокацию, которую ValueTask может избежать.
public ValueTask GetUserAsync(Guid id)
{
if (_cache.TryGetValue(id, out var user))
{
return ValueTask.FromResult(user);
}

return new ValueTask(LoadFromDatabaseAsync(id));
}

private async Task LoadFromDatabaseAsync(Guid id)
{
var result = await dbContext.Users.FirstOrDefaultAsync(u => u.Id == id);

return result;
}

Когда метод возвращает ValueTask, возможны 2 сценария:
1) Если результат уже есть, метод возвращает ValueTask.FromResult(). Результат хранится внутри структуры, лишних аллокаций нет, await завершится сразу.
2) Если нужно дождаться асинхронной операции, ValueTask оборачивает обычный Task, и await работает как обычно. Аллокация есть — но только в этом случае.

Таким образом, не стоит навешивать везде ValueTask. Если метод вызывается десятки тысяч раз в секунду, тогда действительно ValueTask может существенно снизить нагрузку на GC и улучшить производительность 👥.

1.5k 0 30 12 29
Catalog
Channels and groups catalog Channels compilations Search for channels Add a channel/group
Ratings
Rating of Telegram channels Rating of Telegram groups Posts rating Ratings of brands and people
API
API statistics Search API of posts API Callback
Our channels
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Read
Академия TGStat Telegram Research 2019 Telegram Research 2021 Telegram Research 2023
Contacts
Справочный центр Support Email Jobs
Miscellaneous
Terms and conditions Privacy policy Public offer
Our bots
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot