ManualResetEvent vs AutoResetEvent

I want to signal all of my threads waiting for WaitHandle and move them from the Wait Queue to Ready Queue.

There is a small, but significant difference between these two. The main difference comes from the names, when in AutoResetEvent signales (releases) one thread, waiting in the Wait queue and then automatically returns to non-signaled state. Strictly said:
AutoResetEvent will pick and signal just for one thread of more waiting threads.

In the other hand, using ManualResetEvent, you have much more control over the situation. When some thread (producer) will signal (Set), all waiting threads are signaled (released) and enqued to the Ready Queue. Which means they continue from their Wait command.
In this situation you are getting more control in your hands to pick up, which of the waiting threads should take the resource, or process some workitem. The rest of threads can be put in consequent waiting if needed.

Example:

I have a bunch of threads, which are waiting for signal.

First lets try what happens with AutoResetEvent:

image
Clearly shows how just first thread is signalled

ManualResetEvent example

image
This looks much better, all the waiting threads received the signal

And finally, the code which produced this:

class Program
    {
        static ManualResetEvent mre;
        static void Main(string[] args)
        {
            mre = new ManualResetEvent(false);
            var maxT = 3;
            var threads = new List();
            for (int i = 0; i < maxT; i++)
			{
                var t1 = new Thread(Program.T1Proc);
                t1.Start(i);
                threads.Add(t1);
			}
            Thread.Sleep(1000);
            Console.WriteLine("Sleeping for 1 sec");
            Thread.Sleep(1000);
            Console.WriteLine("Setting..");
            mre.Set();
            Console.ReadLine();
        }
        static void T1Proc(object state)
        {
            Console.WriteLine(" thread " + state + " waiting");
            bool received = mre.WaitOne(5000);
            if (received)
                Console.WriteLine(" thread " + state + " received signal");
            else
                Console.WriteLine(" thread " + state + " not received signal");
        }
    }