繁体   English   中英

AutoResetEvent和ManualResetEvent之间的混合

[英]Hybrid between AutoResetEvent and ManualResetEvent

我想知道是否有任何混合EventWaitHandle会在调用.Set()时像AutoResetEvent一样自动重置其状态,同时允许每个执行.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);
        }
    }

}

使用Monitor.PulseAll()代替。 示例代码在此处被称为“绑定缓冲区”。 在.NET 4中以BlockingCollection <>的形式提供。

在不了解您如何使用它的情况下很难说,但这听起来像一个信号量可能很好地解决了这个问题。 您释放信号量N次。 这样就可以运行N个线程。 释放N个线程后,将重置信号灯。 请注意,从技术上讲,这不一定是N个单独的线程-它可以是1个线程释放N次。

这样,如果您需要/想要确保要释放N个单独的线程,则可能(为了一种可能)想要创建2个单独的信号量,在过程的连续步骤中在两个信号量之间交替。 N个线程等待第一个信号量。 释放N次后,每个线程都会运行,然后等待另一个信号量。 最终所有线程将被第一个信号量释放并运行,这将重置该信号量。

然后,您可以使用其他信号量执行下一个处理步骤。

但是请注意,这与线程趋于最佳工作的方式有些相反。 您正在强迫所有线程保持同步,但是如果您让它们尽可能“自由”运行,它们通常处于最佳状态。

暂无
暂无

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

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