Гибрид между AutoResetEvent и ManualResetEvent - PullRequest
1 голос
/ 28 сентября 2011

Мне было интересно, есть ли какой-нибудь гибридный EventWaitHandle, который будет автоматически сбрасывать свое состояние, как AutoResetEvent, когда вызывается .Set () и одновременно позволяет всем, кто сделал .WaitOne (), проходить то же самое, что делает ManualResetEvent.

Единственное решение, которое я придумал, - это очень уродливое решение для использования ManualResetEvent и выполнения следующих действий:

event.Set();
Thread.Sleep(100);
event.Reset();

Какой лучший способ сделать это?Спасибо.

UPD: Спасибо Гансу Я предложил следующее решение.Похоже, это работает:

class HybridWaitHandle
{

    private bool signal = false;
    private readonly object locker = new object();
    private int blocked = 0;

    void WaitOne()
    {
        lock (locker)
        {
            blocked++;

            while (!signal) Monitor.Wait(locker);

            blocked--;

            if (blocked == 0)
                signal = false;
        }
    }

    void Set()
    {
        lock (locker)
        {
            signal = true;
            Monitor.PulseAll(locker);
        }
    }

}

Ответы [ 2 ]

2 голосов
/ 28 сентября 2011

Вместо этого используйте Monitor.PulseAll ().Известный как «ограниченный буфер», пример кода здесь .Доступно в .NET 4 как BlockingCollection <>.

1 голос
/ 28 сентября 2011

Трудно сказать, не зная больше о том, как вы его используете, но похоже, что подсчитанный семафор вполне может решить проблему.Вы выпускаете семафор N раз.Это позволяет N потоков работать.Когда N потоков были освобождены, семафор сбрасывается.Обратите внимание, что технически это не обязательно N отдельных потоков - это может быть 1 поток, выпущенный N раз.

Таким образом, если вы хотите / хотите убедиться, что вы выпускаете N отдельных потоков, вы можете(для одной возможности) хотите создать 2 отдельных семафора, чередуя их для последовательных шагов процесса.N потоков ожидают первого семафора.Когда вы отпускаете его N раз, каждый поток запускается, а затем ожидает семафор other .В конце концов все потоки будут освобождены первым семафором и запущены, что приведет к сбросу этого семафора.

Затем вы можете выполнить следующий шаг обработки, используя другой семафор.

Обратите внимание, однако, чтомногое из этого противоречит тому, как потоки работают лучше всего.Вы заставляете все потоки оставаться в режиме блокировки, но они, как правило, в лучшем виде, если вы просто позволяете им работать как можно более «свободно».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...