混合了AutoResetEvent和ManualResetEvent

本文关键字:ManualResetEvent AutoResetEvent 混合 | 更新日期: 2023-09-27 18:10:01

我想知道是否有任何混合EventWaitHandle,将自动重置它的状态作为AutoResetEvent正在做时。set()被调用,同时将允许每个人做。waitone()传递相同的ManualResetEvent正在做。

我想到的唯一一个解决方案是一个非常丑陋的一个使用ManualResetEvent,并做以下操作:

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

做这件事的更好的方法是什么?谢谢。

乌利希期刊指南:感谢汉斯,我想出了以下解决方案。

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

混合了AutoResetEvent和ManualResetEvent

使用Monitor.PulseAll()代替。被称为"有界缓冲区",示例代码在这里。可在。net 4中作为BlockingCollection<>.

在不了解如何使用它的情况下很难说,但听起来计数信号量可能相当适合这个问题。释放信号量N次。这允许运行N个线程。当N个线程被释放时,信号量被重置。请注意,从技术上讲,这并不一定是N个单独的线程——它可能是一个线程释放N次。

因此,如果您需要/想要确保您正在释放N个单独的线程,您可能(对于一种可能性)想要创建2个单独的信号量,在进程的连续步骤中在两个信号量之间交替。N个线程等待第一个信号量。当您释放它N次时,每个线程都运行,然后等待另一个信号量。最后,所有线程将被第一个信号量释放并运行,这将重置该信号量。

然后可以使用另一个信号量执行下一个处理步骤。

但是,请注意,这在很大程度上与线程的最佳工作方式背道而驰。你是在强迫所有的线程保持锁步状态,但如果你只是让它们尽可能"自由"地运行,它们通常会处于最佳状态。
相关文章:
  • 没有找到相关文章