Ниже приведен класс, который имеет метод "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. Я цитирую соответствующую часть приведенной ниже документации:
Если миллисекундыTimeout равно нулю, метод не блокируется. Он проверяет состояние дескриптора ожидания и немедленно возвращается.
В цикле do..while я вызываю метод Установить. Это освобождает один поток, который может быть заблокирован из-за вызова метода WaitOne (закодированного внутри метода "SomeMethod" ). Затем я проверяю состояние объекта theEvent, чтобы узнать, сигнализировало ли оно. Этот тест выполняется путем вызова перегруженной версии метода WaitOne, который принимает параметр тайм-аута. Аргумент, который я использую, когда я вызываю метод WaitOne, равен нулю, что в соответствии с документацией приводит к тому, что вызов немедленно возвращается с логическим значением. Если возвращаемое значение истинно, объект 'theEvent' находился в сигнальном состоянии. Если по вызову метода WaitOne в методе "SomeMethod" был заблокирован хотя бы один поток, вызов метода "Set" (закодированный внутри метода "UnblockAll" ) разблокирует его. Следовательно, вызов метода "WaitOne" в конце инструкции do..while в методе "UnblockAll" возвращает false. Возвращаемое значение истинно только в случае, если потоки не заблокированы.
Является ли приведенное выше обоснование правильным, и правильно ли это, является ли метод стандартным способом решения моей проблемы? Я пытаюсь использовать это решение в первую очередь на платформе .net compact-framework 2.0.