Есть ли способ пробудить спящий поток на С#? Итак, спать он долгое время и разбудить его, когда вы хотите, чтобы работа была обработана?
Есть ли способ разбудить спящую нить?
Ответ 1
Объект AutoResetEvent
(или другой WaitHandle
) может использоваться для сна до тех пор, пока не будет получен сигнал из другого потока:
// launch a calculation thread
var waitHandle = new AutoResetEvent(false);
int result;
var calculationThread = new Thread(
delegate
{
// this code will run on the calculation thread
result = FactorSomeLargeNumber();
waitHandle.Set();
});
calculationThread.Start();
// now that the other thread is launched, we can do something else.
DoOtherStuff();
// we've run out of other stuff to do, so sleep until calculation thread finishes
waitHandle.WaitOne();
Ответ 2
Если ваш поток находится внутри вызова Sleep
, тогда нет (обычно) способа его разбудить. (Единственное исключение, о котором я знаю, - это Java, который позволяет сон заканчиваться раньше, если какой-либо другой поток вызывает thread.interrupt()
.)
Образец, о котором вы говорите, по-видимому, вызывает событие: поток содержит цикл, в верхней части которого он ожидает события. Если событие в настоящий момент отключено, поток "спит", пока какой-либо другой поток не возбудит событие. В этот момент спящий поток просыпается и продолжает свою работу, пока в следующий раз через цикл, когда он спит, чтобы ждать другого события.
Ответ 3
public void WakeUp()
{
if (Thread.CurrentThread.ThreadState == ThreadState.WaitSleepJoin)
Thread.CurrentThread.Interrupt();
}
Ответ 4
Лучшим решением было бы использовать объекты Task
со значением по умолчанию TaskFactory
. Этот API (внедренный в .NET 4.0) использует пул потоков с очередями поиска работы и всем этим интересным материалом.
Если .NET 4.0 недоступен, используйте ThreadPool
, который имеет встроенную рабочую очередь (которая выполняет некоторую балансировку пула, но не в той же области, что и пул потоков 4,0).
Если вы действительно должны сделать это самостоятельно, я рекомендую BlockingCollection<T>
, который является блокирующей очередью потребителей/производителей, добавленной в .NET 4.0.
Если вы действительно должны сделать это самостоятельно и не можете использовать .NET 4.0, вы можете использовать ManualResetEvent
или AutoResetEvent
вместе с lock
защищенной очередью работы.
Ответ 5
Была ли эта помощь нить? С# имеет хорошую функциональность для потока обработки событий. Я выполнил большую часть своей работы в Python, но у С#, похоже, есть сплошные библиотеки для блокировки потоков.