Имеет ли смысл Task.Delay в отдельном потоке?

2

Я знаю, что использование Thread.Sleep в задаче является немой идеей, потому что это заблокирует этот поток в пуле потоков. Однако, если у меня есть поток, посвященный чему-то, созданному new Thread(new ThreadStart(Foo)), действительно ли имеет смысл Task.Delay? Во всяком случае, ничто не будет использовать этот поток. Мне также интересно, какой именно эффект будет иметь Task.Delay. Он не поместит поток в сон, так будет ли он действовать как ожидание вращения? Это было бы намного хуже, чем сон. Не так ли?

  • 0
    Легко: не смешивайте TPL с потоками. TPL именно для того, чтобы не иметь дело с потоками. Скорее всего, вам нужен Task.Run(() => Foo()) и сделать Foo() async Task await Task.Delay которой вы используете await Task.Delay . Обратите внимание, однако, что большинство применений Sleep / Delay предназначены для обходных путей, а не для решения.
  • 0
    @CamiloTerevinto Если Foo уже асинхронный, нет причины вызывать его из Task.Run .
Показать ещё 2 комментария
Теги:
multithreading

1 ответ

7

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

Чтобы ответить на ваши конкретные вопросы:

Он не поместит поток в сон, так будет ли он действовать как ожидание вращения?

Нет.

Это было бы намного хуже, чем сон. Не так ли?

Да, это было бы ужасно! У него были бы все нижние стороны спящего потока, но он потреблял бы энергию и выделял бы тепло. Вы не просто оплачиваете накладные расходы на выделение потока, вы будете активно тратить силы на отсутствие выгоды. Единственный раз, когда вы когда-либо захотите отложить ожидание, - это когда вы ждёте чего-то, что произойдет за значительно меньшее время, чем квант потока. Spin ждет наносекунды или худший случай, для микросекунд, а не для миллисекунд. Вы хотите отложить ожидание вещей, требующих нескольких инструкций, и мы запускаем миллиарды инструкций в секунду.

Основываясь на вашем вопросе, мое подозрение: (1) вы вообще не понимаете, что делает Task.Delay, и (2) вы произвольно выделяете поток.

Позвольте сначала сказать, что делает Task.Delay.

Task.Delay немедленно возвращает объект, который представляет задачу задержки на некоторое количество миллисекунд.

Это все, что он делает.

В самом деле.

Это фактически не задерживается на любое количество миллисекунд. Он возвращает задачу, которая представляет собой концепцию задержки. Удостоверьтесь, что это ясно в вашей голове.

Если вы спросите задачу, будет ли она завершена или нет, она скажет вам, прошло ли это количество секунд.

Если вы назначаете некоторую функцию в качестве продолжения этой задачи, это продолжение будет запланировано для выполнения в текущем контексте в какой-то момент после завершения задачи.

Что же тогда await Task.Delay(whatever); делать?

Я просто сказал, что он делает. Task.Delay возвращает задачу, которая представляет задержку. await проверки, чтобы проверить, завершена ли эта задача. Если это так, программа продолжается как обычно. Если задача не завершена, то местоположение await становится точкой продолжения задачи, и метод возвращается к вызывающему. Затем выполнение продолжения будет выполняться в текущем контексте в какой-то момент в будущем после завершения задачи.

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню