简体   繁体   English

AutoResetEvent和ManualResetEvent之间的混合

[英]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. 我想知道是否有任何混合EventWaitHandle会在调用.Set()时像AutoResetEvent一样自动重置其状态,同时允许每个执行.WaitOne()的人都像ManualResetEvent一样传递。

The only one solution i came up is a very ugly one to use ManualResetEvent and to do the follwoing: 我提出的唯一解决方案是使用ManualResetEvent并进行以下操作的非常丑陋的解决方案:

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. UPD:谢谢汉斯,我想出了以下解决方案。 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. 使用Monitor.PulseAll()代替。 Known as "bounded buffer", sample code is here . 示例代码在此处被称为“绑定缓冲区”。 Available in .NET 4 as BlockingCollection<>. 在.NET 4中以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. 您释放信号量N次。 That lets N threads run. 这样就可以运行N个线程。 When N threads have been released, the semaphore is reset. 释放N个线程后,将重置信号灯。 Note that technically, this isn't necessarily N separate threads -- it could be 1 thread released N times. 请注意,从技术上讲,这不一定是N个单独的线程-它可以是1个线程释放N次。

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个单独的线程,则可能(为了一种可能)想要创建2个单独的信号量,在过程的连续步骤中在两个信号量之间交替。 N threads wait on the first semaphore. N个线程等待第一个信号量。 When you release it N times, each thread runs, and then waits on the other semaphore. 释放N次后,每个线程都会运行,然后等待另一个信号量。 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. 您正在强迫所有线程保持同步,但是如果您让它们尽可能“自由”运行,它们通常处于最佳状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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