我想知道是否有任何混合EventWaitHandle将自动重置它的状态,因为当调用.Set()时AutoResetEvent正在执行,同时将允许每个执行.WaitOne()的人传递与ManualResetEvent相同的操作。
我提出的唯一一个解决方案是使用ManualResetEvent并执行以下操作非常难看:
event.Set();
Thread.Sleep(100);
event.Reset();
更好的方法是什么? 感谢。
UPD: Thansk和Hans我提出了以下解决方案。 看起来很有效:
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);
}
}
}
答案 0 :(得分:2)
使用Monitor.PulseAll()代替。称为“有界缓冲区”,示例代码为is here。在.NET 4中可用作BlockingCollection<>。
答案 1 :(得分:1)
如果不了解更多关于你如何使用它的话,说起来有点难,但听起来像计数的信号量可能很适合这个问题。你释放信号量N次。这让N个线程运行。释放N个线程后,信号量将被重置。请注意,从技术上讲,这不一定是N个单独的线程 - 它可能是1次线程释放N次。
因此,如果您需要/想要确保释放N个单独的线程,您可能(对于一种可能性)想要创建2个单独的信号量,在这两个信号量的连续步骤之间交替。 N个线程在第一个信号量上等待。当您释放N次时,每个线程都会运行,然后等待其他信号量。最终所有线程将由第一个信号量释放并运行,这将重置该信号量。
然后,您可以使用其他信号量执行下一个处理步骤。
但是,请注意,大部分内容与线程的运行方式有些相反。你强迫所有线程保持锁定步骤,但如果你让它们尽可能“自由”地运行,它们通常会处于最佳状态。