多线程都在等待一个事件? [英] Multiple threads waiting on one event?
问题描述
什么(我认为)我要的是一个的AutoResetEvent
多个线程可以等待,都被当它的设置恢复。
What (I think) I want is the equivelant of an AutoResetEvent
that multiple threads can wait on, all to be resumed when it's set.
我知道这可以通过让一个的AutoResetEvent
每个线程和设定他们每个人实现 - 但有一个更简单的方法? ?不依赖于eventhandles阵列的一种方法。
I know this can be achieved by having one AutoResetEvent
per thread and setting each of them - but is there an easier way? A way that doesn't depend on arrays of eventhandles?
有效什么(我认为)我想是能够做到这一点:
Effectively what (I think) I'd like is to be able to do this:
private volatile string state;
private MultiEventHandle stateChanged = new MultiEventHandle();
public void WaitForBlob()
{
while (true)
{
object saved = stateChanged.Current; // some sentinel value
if (state == "Blob") break;
stateChanged.WaitTilNot(saved); // wait til sentinel value != "current"
}
}
public void SetBlob()
{
state = "Blob";
stateChanged.Change(); // stateChanged.Current becomes a new sentinel object
}
也就是说,任意数量的线程可以调用 WaitForBlob
,并且在任何时候(没有竞争条件)的setBlob
可以通过另一个线程调用,所有等待的线程会立即探测到这一变化 - 重要的是,没有自旋锁或Threading.Sleeps
ie, any number of threads can call WaitForBlob
, and at any time (no race conditions) SetBlob
can be called by yet another thread, and all waiting threads will detect the change immediately - and importantly, with no spin locks or Threading.Sleeps.
现在,我想我可以实现一个 MultiEventHandle
相对容易。但我的问题是...有没有更好的办法?当然,我要对此错误的,因为它必须是一个相当常见的情况,但我似乎无法找到工作的内置工具。我怕我可能会去这里发明了方轮..
Now I think I can implement a "MultiEventHandle
" relatively easily. But my question is... is there a better way? Surely I'm going about this wrong as it must be a pretty common use case, but I can't seem to find an in-built tool for the job. I'm afraid I may be going about inventing a square wheel here..
推荐答案
我已经结束了一个可能的解决方案成使用Monitor.PulseAll /等待幕后WatchedVariable级(学习一些有关的过程中Monitor类)。如果任何人在这里发帖曾经运行到同样的问题 - 可能是不可变的数据结构部分使用。 。感谢乔恩斯基特援助
I've wrapped up a possible solution into a "WatchedVariable" class using Monitor.PulseAll/Wait behind the scenes (learning a bit about the Monitor class in the process). Posting here in case anyone else ever runs into the same problem - may be of some use with immutable data structures. Thanks to Jon Skeet for assistance.
用法:
private WatchedVariable<string> state;
public void WaitForBlob()
{
string value = state.Value;
while (value != "Blob")
{
value = state.WaitForChange(value);
}
}
实施
Implementation:
public class WatchedVariable<T>
where T : class
{
private volatile T value;
private object valueLock = new object();
public T Value
{
get { return value; }
set
{
lock (valueLock)
{
this.value = value;
Monitor.PulseAll(valueLock); // all waiting threads will resume once we release valueLock
}
}
}
public T WaitForChange(T fromValue)
{
lock (valueLock)
{
while (true)
{
T nextValue = value;
if (nextValue != fromValue) return nextValue; // no race condition here: PulseAll can only be reached once we hit Wait()
Monitor.Wait(valueLock); // wait for a changed pulse
}
}
}
public WatchedVariable(T initValue)
{
value = initValue;
}
}
虽然它是通过我的测试情况下,使用你自己的风险。
Whilst it's passed my test cases, use at your own risk.
现在来咨询荟萃找出哪个回答我应该接受..
Now to consult meta to figure out which answer I'm supposed to accept..
这篇关于多线程都在等待一个事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!