c# - AutoResetEvent 设置后立即复位

标签 c# multithreading autoresetevent

考虑以下模式:

private AutoResetEvent signal = new AutoResetEvent(false);

private void Work()
{
    while (true)
    {
        Thread.Sleep(5000);
        signal.Set();
        //has a waiting thread definitely been signaled by now?
        signal.Reset();
    }
}

public void WaitForNextEvent()
{
    signal.WaitOne();
}

此模式的目的是允许外部消费者等待特定事件(例如 - 消息到达)。 WaitForNextEvent 不是从类中调用的。

举一个大家应该很熟悉的例子,考虑System.Diagnostics.Process。它公开了一个 Exited 事件,但它也公开了一个 WaitForExit 方法,允许调用者同步等待直到进程退出。这就是我要在这里实现的目标。

我需要 signal.Reset() 的原因是,如果线程调用 WaitForNextEvent after signal.Set() 已经被调用(或者换句话说,如果在没有线程等待时调用了 .Set),它会立即返回,因为事件之前已经发出信号。

问题

  • 是否保证调用 WaitForNextEvent() 的线程将在 signal.Reset() 被调用之前收到信号?如果不是,还有哪些其他解决方案可以实现 WaitFor 方法?

最佳答案

不要使用 AutoResetEventManualResetEvent,而是使用:

public sealed class Signaller
{
    public void PulseAll()
    {
        lock (_lock)
        {
            Monitor.PulseAll(_lock);
        }
    }

    public void Pulse()
    {
        lock (_lock)
        {
            Monitor.Pulse(_lock);
        }
    }

    public void Wait()
    {
        Wait(Timeout.Infinite);
    }

    public bool Wait(int timeoutMilliseconds)
    {
        lock (_lock)
        {
            return Monitor.Wait(_lock, timeoutMilliseconds);
        }
    }

    private readonly object _lock = new object();
}

然后像这样更改您的代码:

private Signaller signal = new Signaller();

private void Work()
{
    while (true)
    {
        Thread.Sleep(5000);
        signal.Pulse(); // Or signal.PulseAll() to signal ALL waiting threads.
    }
}

public void WaitForNextEvent()
{
    signal.Wait();
}

关于c# - AutoResetEvent 设置后立即复位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18609285/

相关文章:

c# - 有类之类的东西可以实现吗?

c# - 在代码隐藏中将模型数组绑定(bind)到 View 模型

android - 用于 httppost 的线程和异步任务任务

c++ - 使用 Threads c++ 时套接字无法正确打开

AutoResetEvent 的 C# 线程问题

c# - 如何最好地处置因 AutoResetEvent.WaitOne() 而处于休眠状态的线程

c# - 为什么对级联 ManualResetEvent 的多次等待会使执行时间增加三倍?

c# - 如何排列表格中的项目 - MVC3 View (Index.cshtml)

C# 操作溢出尝试将有效值分配给 double

php - Android:后台线程中的PHP