Подтвердить что ты не робот

Is Thread.Sleep(Timeout.Infinite); эффективнее, чем while (true) {}?

У меня есть консольное приложение, которое я хотел бы держать открытым все время, все еще слушая события. Я тестировал Thread.Sleep(Timeout.Infinite); и while (true) { }, и оба разрешения позволяют поднимать события при открытии консольного приложения. Есть ли тот, который я должен использовать над другим? Если поток спал, есть ли что-то, что я не должен делать, например, изменение статической коллекции, объявленной в области класса?

4b9b3361

Ответ 1

Я бы рекомендовал использовать ManualResetEvent (или другой WaitHandle) и вызывать ManualResetEvent.WaitOne.

Это будет иметь схожий эффект для сна навсегда, за исключением того, что он предоставляет вам чистый способ выйти из вашего бесконечного "блока" по желанию (вызывая Set() в событии).

Использование while(true) будет потреблять циклы процессора, поэтому определенно чего-то избежать.

есть ли что-то, чего я не должен делать, например, изменение статического набора, объявленного в области класса?

В общем, нет. Поскольку ваш поток будет заблокирован, не должно возникать проблем с синхронизацией с использованием общих данных (если элементы в коллекции не имеют особых требований, таких как элементы пользовательского интерфейса, которые должны использоваться в потоке с надлежащим контекстом синхронизации.)

Ответ 2

В отличие от while(true)..., Thread.Sleep не использует циклы CPU, поэтому в этом смысле сон более эффективен. В общем случае использование Busy Waiting вне spinlocks сильно обескуражено.

Если поток спал, есть ли что-то, что я не должен делать?

Поскольку ваш поток заблокирован при входе в Thread.Sleep, все, что вы хотите сделать с его ресурсами, - это честная игра.

Ответ 3

Я думаю, что вызов

while (true) { ... } 

является вычислительно интенсивным, так как поток никогда не останавливается, wheareas

Thread.Sleep(Timeout.Infinite);

фактически получает поток для сна с помощью собственных планировщиков ОС. И тогда поток фактически останавливается, поэтому я полагаю, что это менее требовательно к вычислению.

Ответ 4

Да, while(true) потребляет процессор, а sleep() работает умнее: Функция sleep() помещает текущий контекст выполнения в режим сна; он делает это, вызывая syscall, чтобы вызвать функцию сна ядра, которая атомарно (a) устанавливает таймер пробуждения
(б) отмечает текущий процесс как спальный
(c) ждет, пока не произойдет срабатывание таймера пробуждения или произойдет прерывание.

Если вы вызываете sleep(), CPU может выполнять другую работу.

Это одна из причин, почему sleep() полезен.

Полезная ссылка - Будьте осторожны при использовании сна

Ответ 5

Вызов метода Thread.Sleep заставляет текущий поток немедленно блокировать количество миллисекунд или временной интервал, который вы передаете методу, и дает оставшуюся часть своего временного фрагмента другому потоку.

https://msdn.microsoft.com/en-us/library/tttdef8x(v=vs.110).aspx

Ответ 6

Начиная с С# 7.1 вы можете сделать метод Main асинхронным. Это означает, что вместо использования занятое ожидание или спящий режим с блокировкой потоков можно асинхронно приостановить метод Main в качестве задачи. Таким образом, поток, запустивший Main, не будет заблокирован. А с помощью Cts.Cancel(); вы можете легко выпустить главную задачу для выхода из приложения.

readonly CancellationTokenSource Cts = new CancellationTokenSource();
static async Task Main(string[] args)
{
    /* your code here */

    await Task.Delay(Timeout.Infinite, Cts.Token);
}