Когда использовать Task.Delay, когда использовать Thread.Sleep?

Существуют ли правильные правила для использования Task.Delay против Thread.Sleep ?

  • В частности, существует ли минимальное значение для обеспечения эффективности / эффективности над другой?
  • Наконец, поскольку Task.Delay вызывает переключение контекста на конечный компьютер async / wait, есть ли накладные расходы на его использование?

Используйте Thread.Sleep если вы хотите заблокировать текущий stream.

Используйте Task.Delay если вы хотите логическую задержку, не блокируя текущий stream.

Эффективность не должна быть главной проблемой этих методов. Их первичное использование в реальном мире – это таймеры повтора для операций ввода-вывода, которые составляют порядка секунд, а не миллисекунд.

Самая большая разница между Task.Delay и Thread.Sleep заключается в том, что Task.Delay предназначен для асинхронного запуска. Не имеет смысла использовать Task.Delay в синхронном коде. ОЧЕНЬ плохая идея использовать Thread.Sleep в асинхронном коде.

Обычно вы вызываете Task.Delay() с ключевым словом Task.Delay() :

 await Task.Delay(5000); 

или, если вы хотите запустить код до задержки:

 var sw = new Stopwatch(); sw.Start(); Task wait = Task.Delay(5000); Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds); await wait; 

Угадайте, что это будет печатать? Запуск за 0.0070048 секунд. Если мы переместим await wait выше Console.WriteLine , оно будет печатать Running за 5.0020168 секунд.

Давайте посмотрим на разницу с Thread.Sleep :

 class Program { static void Main(string[] args) { Task wait = asyncTask(); syncCode(); wait.Wait(); Console.ReadLine(); } static async Task asyncTask() { var sw = new Stopwatch(); sw.Start(); Console.WriteLine("async: Starting"); Task wait = Task.Delay(5000); Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds); await wait; Console.WriteLine("async: Running for {0} seconds", sw.Elapsed.TotalSeconds); Console.WriteLine("async: Done"); } static void syncCode() { var sw = new Stopwatch(); sw.Start(); Console.WriteLine("sync: Starting"); Thread.Sleep(5000); Console.WriteLine("sync: Running for {0} seconds", sw.Elapsed.TotalSeconds); Console.WriteLine("sync: Done"); } } 

Попробуйте предсказать, что это будет печатать …

async: запуск
async: Запуск за 0.0070048 секунд
синхронизация: запуск
async: Запуск за 5.0119008 секунд
async: Готово
sync: Запуск за 5.0020168 секунд
sync: Done

Кроме того, интересно заметить, что Thread.Sleep гораздо точнее, точность ms не является проблемой, а Task.Delay может занимать минимум 15-30 мс. Накладные расходы по обеим функциям минимальны по сравнению с точностью до мс, которую они имеют (используйте Stopwatch если вам нужно что-то более точное). Thread.Sleep все еще связывает ваш Thread, Task.Delay отпустите его, чтобы выполнить другую работу, пока вы ждете.

если текущий stream убит и вы используете Thread.Sleep и он выполняется, тогда вы можете получить ThreadAbortException . С помощью Task.Delay вы всегда можете предоставить токен отмены и изящно убить его. Это одна из причин, по которой я бы выбрал Task.Delay . см. http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspx

Я также согласен, что эффективность в этом случае не имеет первостепенного значения.

Я хочу что-то добавить. На самом деле Task.Delay – механизм ожидания по таймеру. Если вы посмотрите на источник, вы найдете ссылку на class Timer который отвечает за задержку. С другой стороны Thread.Sleep фактически заставляет текущий stream спать, таким образом вы просто блокируете и тратите один stream. В асинхронной модели программирования вы всегда должны использовать Task.Delay() если хотите что-то (продолжение) произойдет после некоторой задержки.

Это функционально эквивалентные операции – они просто создают паузу, но Task.Delay ждет.

Я нашел способ взломать Thread.Sleep , заставляя программу просыпаться периодически и делать события, если вы действительно должны ее использовать. Смотри ниже:

 // Pay attention every 1/10 sec to maintain some UI responsiveness while (val > 0) { Thread.Sleep(100); val = val - 100; Application.DoEvents(); if (val == x) { // You could do some conditional stuff here at specific times } } 

Замените val с желаемой задержкой в ​​миллисекундах. Чем больше вы понижаете значение Thread.Sleep тем больше будет реагировать программа. Кажется приемлемым для меня 100 мс. Лучше всего 50 мс.

  • В чем разница между асинхронным программированием и многоstreamовой обработкой?
  • Как остановить stream, созданный при реализации runnable-интерфейса?
  • Python 2.7: streamовый HTTP-сервер, поддерживающий несколько соединений на одном порту
  • Как Java использует несколько ядер?
  • Как прервать Console.ReadLine
  • Как защитить ресурсы, которые могут использоваться в многопоточной или асинхронной среде?
  • kill -3, чтобы получить java thread dump
  • Заказ streamов для запуска в том порядке, в котором они были созданы / запущены
  • Как отладить многопоточное приложение в IntelliJ?
  • Можно ли использовать мьютекс в многопроцессорном случае в Linux / UNIX?
  • Печать Even and Odd с использованием двух streamов в Java
  • Interesting Posts

    Ошибка HTTP 404.3-Не найден в IIS 7.5

    Доступ запрещен в IE 10 и 11, когда целью ajax является localhost

    NoClassDefFoundError после обновления IntelliJ IDEA

    Распределение Linux с хорошей поддержкой OSS

    Является ли PCI x16 и PCI Express 2.1 одинаковым?

    Как я могу переназначить Ctrl + C, чтобы отправить сигнал прерывания другим ключом?

    CSS @ font-face – что означает «src: local (« ☺ »)?

    API Карт Google V3: странные сбои отображения пользовательского интерфейса (со снимком экрана)

    Почему медленная инструкция цикла? Не удалось ли Intel эффективно внедрить его?

    Использование MySQL с платформой Entity Framework

    Изменение размеров макетов программным способом (как анимация)

    Как узнать, какая программа создает файл / папку на моем диске C:?

    Как слышать звук микрофона над динамиками – Ubuntu karmic

    Проверьте, существует ли значение в массиве Postgres

    Как определить, какой тип слота определен для конкретной PC-карты?

    Давайте будем гением компьютера.