Ниже приведен класс, имеющий метод SomeMethod, который иллюстрирует мою проблему.
class SomeClass
{
AutoResetEvent theEvent = new AutoResetEvent(false);
// more member declarations
public void SomeMethod()
{
// some code
theEvent.WaitOne();
// more code
}
}
Этот метод разработан с учетом потоковой безопасности и будет вызываться в разных потоках. Теперь мой вопрос: как можно разблокировать все потоки, которые вызвали метод WaitOne для объекта theEvent в любой момент времени? Это требование часто возникает в моем проекте, потому что мне нужно иметь возможность корректно останавливать и запускать свою многопоточную программу. Мне кажется, что запустить многопоточную программу довольно просто, но сложно остановить ее.
Вот то, что я пробовал до сих пор, которая, по-видимому, работает. Но является ли это стандартным подходом?
public void UnblockAll()
{
do
{
theEvent.Set();
} while (theEvent.WaitOne(0));
}
Метод UnblockAll является членом класса SomeClass. Используемый здесь метод основан на документации MSDN по методу WaitOne . Я цитирую соответствующую часть документации ниже:
Если значение millisecondsTimeout равно нулю, метод не блокируется. Он проверяет состояние дескриптора ожидания и немедленно возвращается.
В цикле do.. while я вызываю метод Set . Это освобождает один поток, который мог быть заблокирован из-за вызова метода WaitOne (закодированного внутри метода SomeMethod). Затем я проверяю состояние объекта theEvent, чтобы узнать, сигнализирует ли он. Этот тест выполняется путем вызова перегруженной версии метода WaitOne, который принимает параметр тайм-аута. Аргумент, который я использую при вызове метода WaitOne, равен нулю, что согласно документации приводит к немедленному возврату вызова с логическим значением. Если возвращаемое значение - истина, то объект theEvent находился в сигнальном состоянии. Если хотя бы один поток был заблокирован при вызове метода WaitOne в методе SomeMethod, вызов метода Set (закодированный внутри метода UnblockAll) разблокировал бы его. Следовательно, вызов метода WaitOne в конце оператора do..time в методе UnblockAll вернет false. Возвращаемое значение истинно только в том случае, если не было заблокировано ни одного потока.
Верно ли приведенное выше рассуждение и, если верно, является ли метод стандартным способом решения моей проблемы? Я пытаюсь использовать решение в первую очередь на платформе .net compact-framework 2.0.