Есть хорошие правила для использования Task.Delay против Thread.Sleep ?
- В частности, существует ли минимальное значение для обеспечения того, чтобы один был эффективным / действенным по сравнению с другим?
- Наконец, поскольку Task.Delay вызывает переключение контекста на автомате асинхронного ожидания / ожидания, есть ли издержки его использования?
Ответы:
Используйте,
Thread.Sleep
когда вы хотите заблокировать текущий поток.Используйте,
Task.Delay
когда вы хотите, чтобы логическая задержка не блокировала текущий поток.Эффективность не должна быть первостепенной задачей при использовании этих методов. Их основное реальное использование - таймеры повторов для операций ввода / вывода, которые имеют порядок секунд, а не миллисекунд.
источник
Thread.Sleep
заблокирует текущий поток, который вызывает переключение контекста. Если вы используете пул потоков, это также может привести к выделению нового потока. Обе операции довольно тяжелые, в то время как совместная многозадачность, предоставляемаяTask.Delay
etc, предназначена для того, чтобы избежать всех этих издержек, максимизировать пропускную способность, разрешить отмену и обеспечить более чистый код.onesi: I would use
Thread.Sleep` для ожидания внутри синхронного метода. Тем не менее, я никогда не делаю этого в производственном коде; по моему опыту, каждое, чтоThread.Sleep
я когда-либо видел, было показателем какой-то проблемы дизайна, которая должна быть исправлена должным образом.Самое большое различие между
Task.Delay
иThread.Sleep
заключается в том, чтоTask.Delay
он предназначен для асинхронной работы. Не имеет смысла использоватьTask.Delay
в синхронном коде. Это ОЧЕНЬ плохая идея для использованияThread.Sleep
в асинхронном коде.Обычно вы будете звонить
Task.Delay()
сawait
ключевым словом:или, если вы хотите запустить некоторый код до задержки:
Угадайте, что это будет печатать? Запуск за 0,0070048 секунд. Если вместо этого переместить
await delay
вышеуказанноеConsole.WriteLine
, будет напечатано «Запуск в течение 5.0020168 секунд».Давайте посмотрим на разницу с
Thread.Sleep
:Попробуйте предсказать, что это будет печатать ...
Кроме того, интересно отметить, что
Thread.Sleep
это гораздо более точно, точность мс не является проблемой, хотяTask.Delay
может занять минимум 15-30 мс. Затраты на обе функции минимальны по сравнению с точностью до мс, которую они имеют (используйтеStopwatch
Class, если вам нужно что-то более точное).Thread.Sleep
все еще связывает свою Нить,Task.Delay
отпустите ее для выполнения другой работы, пока вы ждете.источник
Thread.Sleep()
потребляет весь поток, который в противном случае мог бы использоваться в другом месте. Если многие задачи выполняются с Thread.Sleep (), существует высокая вероятность исчерпания всех потоков пула потоков и серьезного снижения производительности.async
методов, так как их рекомендуется использовать. Это просто плохая идея запускатьThread.Sleep()
в потоке потоков, а не плохая идея в целом. В конце концов, естьTaskCreationOptions.LongRunning
путь (хотя и обескураженный)Task.Factory.StartNew()
.await wait
Tasl.Delay
использует системный таймер. Поскольку «Системные часы» отсчитывают «с постоянной скоростью», скорость такта системного таймера составляет около 16 мс, любая запрошенная вами задержка будет округлена до количества тактов системных часов, смещенных на время до первого поставить галочку. См. ДокументациюTask.Delay
msdn по адресу docs.microsoft.com/en-us/dotnet/api/… и прокрутите вниз до примечаний.если текущий поток уничтожен, и вы используете
Thread.Sleep
его, и он выполняется, то вы можете получитьThreadAbortException
. При этомTask.Delay
вы всегда можете предоставить токен отмены и изящно убить его. Это одна из причин, я бы выбралTask.Delay
. см. http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspxЯ также согласен с тем, что в данном случае эффективность не имеет первостепенного значения.
источник
await Task.Delay(5000)
. Когда я убиваю задачу, я получаюTaskCanceledException
(и подавляю ее), но моя нить все еще жива. Ухоженная! :)Я хочу кое-что добавить. На самом деле,
Task.Delay
это механизм ожидания на основе таймера. Если вы посмотрите на источник, вы найдете ссылку наTimer
класс, который отвечает за задержку. С другой стороны,Thread.Sleep
фактически заставляет текущий поток спать, таким образом, вы просто блокируете и тратите один поток. В модели асинхронного программирования вы всегда должны использовать,Task.Delay()
если хотите, чтобы что-то (продолжение) произошло после некоторой задержки.источник