简体   繁体   中英

Hybrid between AutoResetEvent and ManualResetEvent

I was wondering if there is any hybrid EventWaitHandle that will auto-reset it's state as AutoResetEvent is doing when .Set() is invoked and simultaneously will allow everybody who did .WaitOne() to pass the same as ManualResetEvent is doing.

The only one solution i came up is a very ugly one to use ManualResetEvent and to do the follwoing:

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

What is the better way to do this ? Thanks.

UPD: Thansk to Hans I came up with the following solution. Looks like it works:

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);
        }
    }

}

Use Monitor.PulseAll() instead. Known as "bounded buffer", sample code is here . Available in .NET 4 as BlockingCollection<>.

It's a bit hard to say without knowing more about how you're using it, but it sounds like a counted semaphore might fit the problem fairly well. You release the semaphore N times. That lets N threads run. When N threads have been released, the semaphore is reset. Note that technically, this isn't necessarily N separate threads -- it could be 1 thread released N times.

As such, if you need/want to assure that you're releasing N separate threads, you may (for one possibility) want to create 2 separate semaphores, alternating between the two for consecutive steps of the process. N threads wait on the first semaphore. When you release it N times, each thread runs, and then waits on the other semaphore. Eventually all the threads will be released by the first semaphore and run, which will reset that semaphore.

Then you can do the next processing step using the other semaphore.

Note, however, that much of this runs somewhat contrary to how threads tend to work best. You're forcing all the threads to remain in lock-step, but they're generally at their best if you just let them run as "freely" as possible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM