Task vs ValueTask



Что такое Task знают все C# разработчики - класс, олицетворяющий длительную операцию в асинхронном программировании.



А вот в 7 версии языка появилась структура ValueTask, и до сих пор не всем ясно её назначение.



Из интересного в ней два поля - первое для хранения задачи, второе для хранения результата (при наличии).



Поскольку Task это класс, то его экземпляр хранится в куче, а значит высвобождением памяти будет заниматься GC.



ValueTask это структура, а значит вероятнее всего окажется на стеке, и расходов на высвобождение памяти будет потрачено существенно меньше.



Соответственно, стоит использовать эту структуру, когда мы ожидаем, что задача будет выполняться синхронно большинство времени (например, закэшированный результат) или расходы на вызов и ожидание обычной задачи будут больше.



Однако, есть ряд ограничений, то есть, нельзя делать следующие вещи:



⭐️ Ожидать задачу конкурентно или несколько раз



⭐️ Вызывать метод AsTask несколько раз



⭐️ Использовать .Result или .GetAwaiter().GetResult(), если задача не завершена



⭐️ Использовать задачу в комбинаторах WhenAll() и WhenAny()