我想做什么
我想创建一些线程,比如线程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();
}
您应该考虑使用信号量,而不是手动重置事件或自动重置事件。
这里的文档中有一个很好的基本示例。
此外,这里还有一个相关的堆栈溢出问题。