如何在每个事件中只向一个线程发出唤醒信号



我想做什么

我想创建一些线程,比如线程A、B、C,并阻止它们直到事件发生。当一个事件发生时,我只想释放一个线程。

例如:

Before event occurs:
Thread A : blocked
Thread B : blocked
Thread C : blocked
After event occurs:
Thread A : blocked
Thread B : unblocked
THread C : blocked

我读到AutoResetEvent可以做到这一点,但我不能指定要解锁哪个线程,ManualResetEvent将解锁所有被阻止的线程。

有没有办法实现我想要做的事情?

创建多个ManualResetEvent实例,每个Thread一个,并在每个Thread中使用ManualResetEvent.WaitOne(),例如

public void StartThreadA()
{
    _mreA = new ManualResetEvent();
    _threadA = new Thread(new ThreadStart(() => 
    {
        _mreA.WaitOne();
        // Continue
    });
}

当你的事情发生时,你可以这样处理:

private void OnSomeEvent()
{
   _mreA.Set();
}

这在规模上是非常有限的,如果你打算使用大量的线程,我建议使用字典来查找每个线程的ManualResetEvent

更新

正如我现在所知,你正在使用一个线程队列,我会做如下操作:

private Queue<ManualResetEvent> _queuedThreads = new Queue<ManualResetEvent>();
public void EnqueueThread()
{
    var mre = new ManualResetEvent();
    var thread = new Thread(new ThreadStart(() =>
    {
        mre.WaitOne();
        // Continue
    });
   _queuedThreads.Enqueue(mre);
}
private void OnEvent()
{
    var mre = _queuedThreads.Dequeue();
    mre.Set();   
}

您应该考虑使用信号量,而不是手动重置事件或自动重置事件。

这里的文档中有一个很好的基本示例。

此外,这里还有一个相关的堆栈溢出问题。

最新更新