Когда использовать задачу.Задержка, когда использовать поток.Спать?



есть ли хорошие правила для того, когда использовать задач.Задержка и нить.Спи?




  • в частности, существует ли минимальное значение для обеспечения того, чтобы один был эффективным/эффективным по сравнению с другим?

  • наконец, начиная с задачи.Задержка вызывает контекстное переключение на асинхронный / ожидающий конечный автомат, есть ли накладные расходы на его использование?

581   5  

5 ответов:

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

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

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

самая большая разница между Task.Delay и Thread.Sleep это Task.Delay предназначен для запуска асинхронных. Не имеет смысла использовать Task.Delay в синхронном коде. Это очень плохая идея, чтобы использовать Thread.Sleep в асинхронный код.

обычно вы будете называть Task.Delay() С await ключевые слова:

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 вместо этого, он будет печатать работает в течение 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");
    }
}

попытаться предсказать, что это будет печатать...

асинхронность: начиная с
асинхронность: работает в течение 0.0070048 секунд
синхронизация: запуск
асинхронность: работает в течение 5.0119008 секунд
асинхронно: готово
синхронизация: работает в течение 5.0020168 секунд
синхронизации: сделали

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

если текущий поток будет убит, и вы используете 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 это механизм ожидания на основе таймера. Если вы посмотрите на источник вы найдете ссылку на Timer класс, который отвечает за задержку. С другой стороны Thread.Sleep на самом деле делает текущий поток в спящий режим, таким образом, вы просто блокируете и тратите один поток. В асинхронной модели программирования вы всегда должны использовать Task.Delay() Если вы хотите, чтобы что-то (продолжение) произошло после некоторой задержки.

это функционально эквивалентные операции-они просто создают паузу, но задачу.Задержка вполне ожидаема.

Comments

    Ничего не найдено.