Как мне разблокировать потоки, которые вызвали метод WaitOne для объекта AutoResetEvent?

Ниже приведен класс, имеющий метод 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.

12
задан ghd 10 May 2011 в 04:04
поделиться