Как я могу вызвать Task & ValueTask внутри ValueTask?

Я хочу вызвать следующий код:

public async ValueTask UserGivenClaim(AppUser user, Organization org, string claim)
{
    var notify = new NotifyClaims(user, org);
    await notify.SetReplyToTask(null, org);
    await NotificationQueue.PushValueTask(notify);
}

В приведенном выше коде SetReplyToTask() возвращает Task, а PushValueTask() возвращает ValueTask. А с точки зрения производительности SetReplyToTask() в 99% случаев выполняется проверка if, которая является истинной, и возвращается. Таким образом, в 99% случаев внутри него не вызываются методы Task.

Объявление UserGivenClaim async позволяет мне звонить await notify.SetReplyToTask(null, org); Будет ли это самый быстрый код? Я беспокоюсь, что упустил преимущество ValueTask, сделав это.

Другая возможность — создать notify.SetReplyToTask() ValueTask. Если в 99% случаев задача не вызывается, стоит ли мне использовать ValueTask?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

await в ValueTask возвращающем async методе не обязательно должны быть одного и того же ожидаемого типа, т. е. только ValueTask или только Task. Ваш пример как раз в порядке.

Один из основных моментов использования ValueTask — это когда асинхронный метод завершится синхронно, как вы отметили:

Если в 99% случаев он не вызывает Задачу, стоит ли мне это делать? используя ValueTask?

Так что если

  1. имея PushValueTask() как ValueTask, мы уверены, что большую часть времени он завершится синхронно
  2. и зная, что SetReplyToTask() хотя и Task возвращается, но, согласно вашим словам, в 99% случаев будет выполняться синхронно.

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

Тем не менее, в документации перечислены два других «требования», которые должны быть выполнены, прежде чем вы откажетесь от настроек по умолчанию Task:

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

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

В документации вы можете увидеть множество ограничений, которые ValueTask имеют, а Task нет, что делает выбор между ними немного более тонким, чем «Выполняется ли синхронно большую часть времени».

Во-первых, спасибо за четкий и полный ответ. Во-вторых, правильно ли будет сказать, что Task и ValueTask функционально одинаковы, но Task всегда устанавливает структуру задачи, а ValueTask устанавливает ее только при необходимости? И поскольку настройка его только в случае необходимости менее эффективна, поэтому я хочу использовать Task, если ему может потребоваться структура задач. ??? ТИА

David Thielen 24.07.2024 16:38

@DavidThielen да. Task и ValueTask функционально одинаковы, только если вы await их. Я не уверен, что вы подразумеваете под «настройкой структуры задач», но я думаю, что вы окажете себе огромную услугу, углубившись в некоторые статьи Стивена Тауба на тему Tasks и async/await. Они помогут вам построить лучшую ментальную модель и устранить большую часть путаницы, которая естественным образом окружает эту тему — это специально для ValueTask.

Ivan Petrov 24.07.2024 20:06

Другие вопросы по теме