如何通知每个事件只唤醒一个线程

时间:2013-12-09 00:13:40

标签: c# multithreading

我想做什么

我想创建一些线程,比如线程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将取消阻止所有被阻止的线程。

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

2 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:0)

您应该考虑使用Semaphore而不是ManualResetEvent或AutoResetEvent。

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

此外,还有related stack overflow question