首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AutoResetEvent累积集()

AutoResetEvent累积集()
EN

Stack Overflow用户
提问于 2018-07-31 13:36:22
回答 1查看 25关注 0票数 0

我编写了这段代码作为概念的证明,以检查我正在试验的当前项目中的一个问题。

代码语言:javascript
复制
var sleeper = new AutoResetEvent(false);

        sleeper.Set();
        sleeper.Set();
        sleeper.Set();

        var ix = 0;
        while(true) {
            sleeper.WaitOne();
            Console.Write(ix++);
        }

令人惊讶的是(至少对我来说)我没有得到我期望的结果。我希望在控制台中打印一个012,但只打印0

  • 我误会什么了?
  • 解决这个问题,得到预期结果的最好方法是哪一种?
EN

回答 1

Stack Overflow用户

发布于 2018-07-31 14:15:08

  1. 实际上,代码的输出是0
  2. AutoResetEvent没有内存,它要么发出信号,要么没有信号。在它发出信号后你就在等着它。在您的案例中,事件的顺序:
代码语言:javascript
复制
- create AutoResetEvent (state = 0)
- signal AutoResetEvent (state = 1)
- signal AutoResetEvent (state = 1)
- signal AutoResetEvent (state = 1)
- start waiting on the event (process the current signalled state of 1 and switch it to 0)
- go on waiting on the event

如msdn AutoResetEvent 描述中所述

此外,如果在没有线程等待且AutoResetEvent已经发出信号时调用Set,则调用没有任何效果。

  1. 要观察所需的行为,您需要第二个线程(因为AutoResetEvent是为线程间通信而创建的)。

像这样的东西应该对你有用

代码语言:javascript
复制
private static AutoResetEvent sleeper;

static void Main()
{
    sleeper = new AutoResetEvent(false);

    Thread t = new Thread(ThreadProc);
    t.Start();

    var ix = 0;
    while(true) 
    {
        sleeper.WaitOne();
        Console.Write(ix++);
    }
}

static void ThreadProc()
{
    Thread.Sleep(1000);
    sleeper.Set();
    Thread.Sleep(1000);
    sleeper.Set();
    Thread.Sleep(1000);
    sleeper.Set();
}
  1. 请注意,AutoResetEvent做而不是保证它将为下面的代码处理3个事件 sleeper.Set();sleeper.Set();sleeper.Set();

正如它的“描述”中提到的,因此出现了Thread.Sleep(1000)位。

不能保证每次调用Set方法都会释放一个线程。如果两个调用太近,以致第二个调用发生在线程被释放之前,则只释放一个线程。就好像第二个电话没有发生一样。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51614731

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档