auto,reset,event,c#,thread

jamesm 7/29/2016 1people says helpful

this is the usage of autoresetevent in c#

C#
 An AutoResetEvent is like a ticket turnstile: inserting a ticket lets exactly one person through. The auto in the classs
name refers to the fact that an open turnstile automatically closes or resets after someone steps through. A thread
waits, or blocks, at the turnstile by calling WaitOne (wait at this one turnstile until it opens), and a ticket is inserted by
calling the Set method. If a number of threads call WaitOne, a queue builds up behind the turnstile. (As with locks, the
fairness of the queue can sometimes be violated due to nuances in the operating system). A ticket can come from any
thread; in other words, any (unblocked) thread with access to the AutoResetEvent object can call Set on it to release
one blocked thread.

You can create an AutoResetEvent in two ways. The first is via its constructor:
var auto = new AutoResetEvent (false);
(Passing true into the constructor is equivalent to immediately calling Set upon it.) The second way to create an
AutoResetEvent is as follows:
var auto = new EventWaitHandle (false, EventResetMode.AutoReset);

        static EventWaitHandle _waitHandle = new AutoResetEvent(false );

        static void Main(string[] args)
        {
            new Thread (Waiter).Start();
            Thread.Sleep(1000); // Pause for a second...
            _waitHandle.Set(); // Wake up the Waiter.

            Console.ReadLine();
        }

        static void Waiter()
        {
            Console.WriteLine("Waiting..." );
            _waitHandle.WaitOne(); // Wait for notification
            Console.WriteLine("Notified" );
        }
  
*************************
        static EventWaitHandle _ready = new AutoResetEvent(false );
        static EventWaitHandle _go = new AutoResetEvent(false );
        static readonly object _locker = new object ();
        static string _message;

        static void Main(string[] args)
        {
            new Thread (Work).Start();
            _ready.WaitOne(); // First wait until worker is ready
            lock (_locker) _message = "ooo" ;
            _go.Set(); // Tell worker to go
            _ready.WaitOne();
            lock (_locker) _message = "ahhh" ; // Give the worker another message
            _go.Set();
            _ready.WaitOne();
            lock (_locker) _message = null ; // Signal the worker to exit
            _go.Set();

            Console.ReadLine();
        }

        static void Work()
        {
            while (true )
            {
                _ready.Set(); // Indicate that we're ready
                _go.WaitOne(); // Wait to be kicked off...
                lock (_locker)
                {
                    if (_message == null ) return; // Gracefully exit
                    Console.WriteLine(_message);
                }
            }
        }
*****************************
In the example below, we use a single AutoResetEvent to signal a worker, which waits when it runs out of tasks (in
other words, when the queue is empty). We end the worker by enqueing a null task:

To ensure thread safety, we used a lock to protect access to the Queue<string> collection. We also explicitly closed the
wait handle in our Dispose method, since we could potentially create and destroy many instances of this class within
the life of the application.

        static void Main(string[] args)
        {
            using (ProducerConsumerQueue q = new ProducerConsumerQueue())
            {
                q.EnqueueTask( "Hello");
                for (int i = 0; i < 10; i  ) q.EnqueueTask("Say "   i);
                q.EnqueueTask( "Goodbye!");
            }
            // Exiting the using statement calls q's Dispose method, which
            // enqueues a null task and waits until the consumer finishes.

            Console.ReadLine();
        }

        class ProducerConsumerQueue : IDisposable
        {
            EventWaitHandle _wh = new AutoResetEvent( false);
            Thread _worker;
            readonly object _locker = new object();
            Queue<string > _tasks = new Queue<string >();
            public ProducerConsumerQueue()
            {
                _worker = new Thread (Work);
                _worker.Start();
            }
            public void EnqueueTask(string task)
            {
                lock (_locker) _tasks.Enqueue(task);
                _wh.Set();
            }
            public void Dispose()
            {
                EnqueueTask( null); // Signal the consumer to exit.
                _worker.Join(); // Wait for the consumer's thread to finish.
                _wh.Close(); // Release any OS resources.
            }
            void Work()
            {
                while (true )
                {
                    string task = null ;
                    lock (_locker)
                        if (_tasks.Count > 0)
                        {
                            task = _tasks.Dequeue();
                            if (task == null ) return;
                        }
                    if (task != null )
                    {
                        Console.WriteLine("Performing task: "   task);
                        Thread.Sleep(1000); // simulate work...
                    }
                    else
                        _wh.WaitOne(); // No more tasks - wait for a signal
                }
            }
        }
 

Report Bug

Please Login to Report Bug

Reported Bugs

Comments

Please Login to Comment

Comments