У меня есть часть работы, которую я делаю в потоке (а не в основном потоке). При определенных обстоятельствах я хотел бы поставить эту нить на 10 секунд. Является ли Thread.Sleep(10000) наиболее ресурсоэффективным способом сделать это?
Ввод текущей нити в сон
Ответ 1
Является ли Thread.Sleep(10000) наиболее ресурсоэффективным способом для этого?
Да в том смысле, что он не занят - ожидание, но отказ от процессора.
Но это тратит поток. Вы не должны масштабировать это для многих спальных потоков.
Ответ 2
Как никто другой не упомянул об этом...
Если вы хотите, чтобы другой поток мог разбудить ваш "спальный" поток, вы можете использовать Monitor.Wait
вместо Thread.Sleep
:
private readonly object sharedMonitor;
private bool shouldStop;
public void Stop()
{
lock (sharedMonitor)
{
shouldStop = true;
Monitor.Pulse(sharedMonitor);
}
}
public void Loop()
{
while (true)
{
// Do some work...
lock (sharedMonitor)
{
if (shouldStop)
{
return;
}
Monitor.Wait(sharedMonitor, 10000);
if (shouldStop)
{
return;
}
}
}
}
Обратите внимание, что мы имеем доступ только к shouldStop
внутри блокировки, поэтому проблем с моделью памяти нет.
Возможно, вам захочется зациклиться на ожидании, пока вы действительно не спали в течение 10 секунд, на всякий случай, если вы получите побочные пробуждения - это зависит от того, насколько важно, чтобы вы больше не работали еще 10 секунд, (Я никогда не знавал, что встречал ложные следы, но я считаю, что они возможны.)
Ответ 3
Сделайте привычку использовать Thread.CurrentThread.Join(timeout) вместо Thread.Sleep.
Разница в том, что Join все равно будет выполнять некоторую пересылку сообщений (например, GUI и COM).
В большинстве случаев это не имеет значения, но это облегчает жизнь, если вам когда-либо понадобится использовать какой-либо объект COM или GUI в вашем приложении.
Ответ 4
Из эффективности ресурсов да.
Для дизайна это зависит от обстоятельств паузы. Вы хотите, чтобы ваша работа была автономной, поэтому, если поток должен приостановиться, потому что он знает, чтобы ждать, тогда поместите паузу в код потока, используя статический метод Thread.Sleep. Если пауза происходит из-за какого-либо другого внешнего события, чем вам нужно управлять обработкой потока, тогда владелец потока должен ссылаться на поток и вызывать childThread.Sleep.
Ответ 5
Да. Нет другого эффективного или безопасного способа спящего потока.
Однако, если вы выполняете какую-либо работу в цикле, вы можете использовать цикл "Спящий режим", чтобы облегчить прерывание потока, если вы хотите отменить свою работу.
Вот пример:
bool exit = false;
...
void MyThread()
{
while(!exit)
{
// do your stuff here...
stuff...
// sleep for 10 seconds
int sc = 0;
while(sc < 1000 && !exit) { Thread.Sleep(10); sc++; }
}
}
Ответ 6
Это будет обрабатывать что-то каждые х секунд без использования потока Не знаете, как не использовать собственный поток, сравнивается с задачей запуска, которая создается каждые две секунды.
public void LogProcessor()
{
if (_isRunning)
{
WriteNewLogsToDisk();
// Come back in 2 seonds
var t = Task.Run(async delegate
{
await Task.Delay(2000);
LogProcessor();
});
}
}