TGStat
TGStat
Введите текст для поиска
Расширенный поиск каналов
  • flag Russian
    Язык сайта
    flag Russian flag English flag Uzbek
  • Вход на сайт
  • Каталог
    Каталог каналов и чатов Региональные подборки Тематические подборки Платные каналы Поиск каналов
    Добавить канал/чат
  • Рейтинги
    Рейтинг каналов Рейтинг чатов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Telegram
  • Продвижение
    Реклама через Яндекс Бизнес Реклама в каналах через TGStat Agency Реклама на сайте TGStat.ru
НеСерьезный шарпист

28 Jun 2025, 18:32

Открыть в Telegram Поделиться Пожаловаться

Столкнулся с тем, что, как выяснилось, не всем очевидно для чего нужен 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
Каталог
Каталог каналов и чатов Подборки каналов Поиск каналов Добавить канал/чат
Рейтинги
Рейтинг каналов Telegram Рейтинг чатов Telegram Рейтинг публикаций Рейтинги брендов и персон
API
API статистики API поиска публикаций API Callback
Наши каналы
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Почитать
Академия TGStat Исследование Telegram 2019 Исследование Telegram 2021 Исследование Telegram 2023
Контакты
Справочный центр Поддержка Почта Вакансии
Всякая всячина
Пользовательское соглашение Политика конфиденциальности Публичная оферта
Наши боты
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot