SpinWait против ожидания ожидания. Какой из них использовать?

Насколько эффективно

SpinWait.SpinUntil(() => myPredicate(), 10000) 

для тайм-аута 10000 мс

или

Thread.Sleep ли использовать опрос Thread.Sleep для того же условия. Например, что-то вроде строк следующей функции SleepWait :

 public bool SleepWait(int timeOut) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); while (!myPredicate() && stopwatch.ElapsedMilliseconds < timeOut) { Thread.Sleep(50) } return myPredicate() } 

Я обеспокоен тем, что все уступки SpinWait не могут быть хорошим шаблоном использования, если мы говорим о тайм-аутах в течение 1 секунды? Действительно ли это предположение?

Какой подход вы предпочитаете и почему? Есть ли еще лучший подход?


Обновление – Стать более конкретным:

Есть ли способ сделать BlockingCollection Pulse спальным streamом, когда он достигнет ограниченной емкости? Я предпочитаю избегать оживленного ожидания, поскольку Марк Гравел предлагает.

Наилучший подход состоит в том, чтобы иметь некоторый механизм для активного обнаружения того, что вещь становится истинной (а не пассивно опроса, чтобы она стала истинной); это может быть любой вид обработки ожиданий или, может быть, Task с Wait или event которое вы можете подписаться, чтобы разблокировать себя. Конечно, если вы делаете такое «подождать, пока что-то не произойдет», это все равно не так эффективно, как просто следующий бит работы, выполненный как обратный вызов , что означает: вам не нужно использовать stream для ожидания. Task имеет ContinueWith для этого, или вы можете просто выполнить работу в event когда оно будет запущено. event , вероятно, самый простой подход, в зависимости от контекста. Task , однако, уже обеспечивает большинство – все, о чем вы здесь говорите, включая механизмы ожидания с тайм-аутом и «обратный вызов».

И да, rotation на 10 секунд не очень велико. Если вы хотите использовать что-то вроде своего текущего кода, и если у вас есть причина ожидать короткой задержки, но вам нужно дать более длинный SpinWait – возможно, SpinWait (скажем) 20 мс и использовать Sleep для остальных?


Повторите комментарий; вот как я зацепил механизм «это полный»:

 private readonly object syncLock = new object(); public bool WaitUntilFull(int timeout) { if(CollectionIsFull) return true; // I'm assuming we can call this safely lock(syncLock) { if(CollectionIsFull) return true; return Monitor.Wait(syncLock, timeout); } } 

с, в коде «вернуть обратно в коллекцию»:

 if(CollectionIsFull) { lock(syncLock) { if(CollectionIsFull) { // double-check with the lock Monitor.PulseAll(syncLock); } } } 

В .NET 4 SpinWait выполняет SpinWait ЦП на 10 итераций до урожая. Но он не возвращается к вызывающей стороне сразу после каждого из этих циклов; вместо этого он вызывает Thread.SpinWait для вращения через CLR (по существу, OS) в течение заданного периода времени. Этот период времени составляет несколько десятков наносекунд, но с каждой итерацией удваивается до тех пор, пока не будут выполнены 10 итераций. Это обеспечивает ясность / предсказуемость в общей длительности отжига (интенсивность процессора), которую система может настраивать в соответствии с условиями (количество ядер и т. Д.). Если SpinWait слишком долгое время находится на стадии SpinWait спина, он будет периодически спать, чтобы другие streamи продолжались (см . Блог Дж. Альбахари для получения дополнительной информации). Этот процесс гарантированно будет поддерживать kernel ​​…

Таким образом, SpinWait ограничивает интенсивность вращения процессора до заданного количества итераций, после чего он дает свой временной срез для каждого спина (фактически вызывая Thread.Yield и Thread.Sleep ), снижая потребление ресурсов. Он также обнаружит, работает ли пользователь на одной основной машине и дает на каждый цикл, если это так.

С Thread.Sleep stream заблокирован. Но этот процесс не будет таким дорогим, как выше, с точки зрения процессора.

  • Java-сервер с многоклиентной связью.
  • Почему бы не начать нить в конструкторе? Как прекратить?
  • межпоточная связь в java
  • вызывающий thread.start () внутри своего собственного конструктора
  • Попытка запуска нескольких HTTP-запросов параллельно, но ограничена Windows (реестром)
  • В чем разница между ожиданием Task и Task .Result?
  • Связаны ли статические переменные между streamами?
  • Ссылка на multithreading?
  • Предотrotation блокировки графического интерфейса Swing во время фоновой задачи
  • C11 GCC threads.h не найден?
  • Сколько памяти занимает мой stream java?
  • Interesting Posts

    Какие инструменты и методы Android лучше всего подходят для поиска утечек памяти / ресурсов?

    @ «Какой-то текст» дает автореализацию или сохранение 1 объекта назад?

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

    scala.concurrent.blocking – что это на самом деле?

    Android с сохранением битовой карты на SD-карту

    Как вызвать другой controller Действие С controllerа в Mvc

    Как изменить файлы конфигурации .NET во время установки?

    Какой RAID-контроллер я должен использовать?

    Сервлет для обслуживания статического содержимого

    В чем разница между MOV и LEA?

    Как удалить все, кроме 10 самых новых файлов в Linux?

    Высокая латентность / пинг для локальных шлюзов WHILE STREAMING

    Обрезать изображение с распознаванием лиц в android

    Apache без подключения к Интернету

    Подавление устаревшего импортного предупреждения в Java

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