Есть ли способ разбудить спящую нить?

Есть ли способ пробудить спящий поток на С#? Итак, спать он долгое время и разбудить его, когда вы хотите, чтобы работа была обработана?

Ответ 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, но у С#, похоже, есть сплошные библиотеки для блокировки потоков.