Когда выбирать ValueTask вместо Task, и какие у него ловушки?
Берите ValueTask, если бóльшая часть вызовов завершается синхронно (кэш, короткие I/O) и вы реально снижаете аллокации; иначе Task проще и часто не медленнее.
Не публикуйте ValueTask без нужды в широких API: потребители могут ждать результат несколько раз или кешировать его — для ValueTask это некорректно (повторное ожидание допустимо только после преобразования в Task).
Если нужно ждать более одного раза или хранить результат, конвертируйте один раз в Task через AsTask() и работайте с ним.
Это структура: может содержать либо значение, либо ссылку на источник (IValueTaskSource). Ошибки владения/повторного ожидания ведут к Undefined Behavior.
В композиции (WhenAll/WhenAny, LINQ over Tasks, сторонние библиотеки) часто всё равно произойдёт аллокация или боксинг — выигрыш исчезает.
Исключения/отмена ведут себя как у Task, но повторное ожидание после ошибки у ValueTask недопустимо.
Типичный кейс: горячие пути ASP.NET Core/парсеры/кэш — измерения показывают пользу; для остального оставляйте Task ради простоты и устойчивости.
🐸Библиотека собеса по С#
Post #871
1.72K