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