多线程都在等待一个事件? [英] Multiple threads waiting on one event?

查看:167
本文介绍了多线程都在等待一个事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么(我认为)我要的是一个的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆