【问题标题】:AutoResetEvent Reset methodAutoResetEvent 重置方法
【发布时间】:2011-08-17 18:42:03
【问题描述】:

有人可以介绍 AutoResetEvent.Reset() 方法的用例吗? 我什么时候以及为什么要使用这种方法? 我了解 WaitOne 和 Set,但这对我来说还不清楚。

【问题讨论】:

  • 为什么要投票结束?这个问题对我来说似乎非常清楚和有用......

标签: c# reset autoresetevent


【解决方案1】:

是的,AutoResetEvent 将在收到等待事件的线程发出信号时自动重置其状态。但是,给定事件可能不再有效,并且自最初设置以来,没有线程在等待 AutoResetEvent。在这种情况下,Reset 方法变得有用

【讨论】:

  • 但是在这种情况下调用 Reset() 有什么好处呢?
  • @anth 它阻止任何尚未调用等待但将在未来某个时间点调用的线程因不再有效的事件而被激活。注意:这本身不足以防止竞争条件,但它可以成为更大解决方案的一部分
【解决方案2】:

看起来它只是继承自EventWaitHandle。可能对同样继承自该类的 ManualResetEvent 更有用?

【讨论】:

    【解决方案3】:

    该方法继承自基类EventWaitHandle,用于将AutoResetEvent(重新)设置为“阻塞”状态。

    因为AutoResetEvent 会在收到信号后立即自动进入该状态,您通常不会在代码中看到此方法,但对于派生自EventWaitHandle 的其他类,它会更有用!

    【讨论】:

      【解决方案4】:

      如果 AutoResetEvent 生产者想要清除事件,您将使用 Reset()。这样,您可以安全地“重置”事件,而不必知道它当前是否已发出信号。如果生产者使用 WaitOne 来“重置”它自己的事件,则存在死锁的风险(即永远不会返回,因为未发出事件信号并且生产者线程被阻塞)。

      【讨论】:

        【解决方案5】:

        重置

        将事件的状态设置为无信号 ,见EventWaitHandle Class

        样品,

        using System;
        using System.Threading;
        namespace ThreadingInCSharp.Signaling
        {
            class Program
            {
                static EventWaitHandle _waitHandle = new AutoResetEvent(false);
                static void Main(string[] args)
                {
                    //The event's state is Signal
                    _waitHandle.Set();
                    new Thread(Waiter).Start();
                    Thread.Sleep(2000);
                    _waitHandle.Set();
                    Console.ReadKey();
                }
                private static void Waiter()
                {
                    Console.WriteLine("I'm Waiting...");
                    _waitHandle.WaitOne();
                    //The word pass will print immediately 
                    Console.WriteLine("pass");
                }
            }
        }
        

        使用重置

        using System;
        using System.Threading;
        namespace ThreadingInCSharp.Signaling
        {
            class Program
            {
                static EventWaitHandle _waitHandle = new AutoResetEvent(false);
                static void Main(string[] args)
                {
                    //The event's state is Signal
                    _waitHandle.Set();
                    _waitHandle.Reset();
                    new Thread(Waiter).Start();
                    Thread.Sleep(2000);
                    _waitHandle.Set();
                    Console.ReadKey();
                }
        
                private static void Waiter()
                {
                    Console.WriteLine("I'm Waiting...");
                    _waitHandle.WaitOne();
                    //The word will wait 2 seconds for printing
                    Console.WriteLine("pass");
                }
            }
        }
        

        【讨论】:

          【解决方案6】:

          在使用 Reset() 时应使用 ManualResetEvent,因为 AutoResetEvent 会在线程发出信号时自行重置。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-08-06
            相关资源
            最近更新 更多