Embedd_0913
Embedd_0913

Reputation: 16555

How to use wait handles in C# threading?

I have three threads in my program and I want that when thread one finishes it signals thread 2 to start and when thread 2 finishes it should signal thread 3 to start.

How can I achieve this, I know there are wait handles to do that in C#, but I don't know how to use them ?

Following is the code of my program:

class Program
    {
        static void Main(string[] args)
        {
            Thread t1 = new Thread(Task1);
            Thread t2 = new Thread(Task2);
            Thread t3 = new Thread(Task3);

            t1.Start();
            t2.Start();
            t3.Start();

            Console.Read();
        }

        public static void Task1()
        {
            Console.WriteLine("I am assigned task 1:");
            for (int i = 0; i < 50; i++)
            {
                Console.WriteLine("Task1" );
            }
        }
        public static void Task2()
        {
            Console.WriteLine("I am assigned task 2:");
            for (int i = 0; i < 50; i++)
            {
                Console.WriteLine("Task2");
            }
        }
        public static void Task3()
        {
            Console.WriteLine("I am assigned task 3:");
            for (int i = 0; i < 50; i++)
            {
                Console.WriteLine("Task3");
            }
        }
    }

Upvotes: 3

Views: 15367

Answers (6)

Sean
Sean

Reputation: 62472

You need to pass events into the threaded functions that indicate what to signal when each one has finished and what to wait on before they run. Take a look at the (untested) code below to see what I mean:

class Program
    {
        static void Main(string[] args)
        {
            Thread t1 = new Thread(Task1);
            ManualResetEvent e1=new ManualResetEvent(false);

            Thread t2 = new Thread(Task2);
            ManualResetEvent e2=new ManualResetEvent(false);

            Thread t3 = new Thread(Task3);
            ManualResetEvent e3=new ManualResetEvent(false);

            t1.Start(()=>Task1(e1));
            t2.Start(()=>Task2(e1,e2));
            t3.Start(()=>Task3(e2,e3);

            Console.Read();

            t1.Join();
            t2.Join();
            t3.Join();
        }

        public static void Task1(EventWaitHandle handle)
        {
            Console.WriteLine("I am assigned task 1:");
            for (int i = 0; i < 50; i++)
            {
                Console.WriteLine("Task1" );
            }
            handle.Set();

        }
        public static void Task2(EventWaitHandle waitFor, EventWaitHandle handle)
        {
            waitFor.WaitOne();

            Console.WriteLine("I am assigned task 2:");
            for (int i = 0; i < 50; i++)
            {
                Console.WriteLine("Task2");
            }

            handle.Set();
        }
        public static void Task3(EventWaitHandle waitFor, EventWaitHandle handle)
        {
            waitFor.WaitOne();

            Console.WriteLine("I am assigned task 3:");
            for (int i = 0; i < 50; i++)
            {
                Console.WriteLine("Task3");
            }

            handle.Set();
        }
    }

Upvotes: 6

Amr Badawy
Amr Badawy

Reputation: 7673

i think using thread.join() will be more simpler any other solution

Upvotes: 0

Ani
Ani

Reputation: 113402

It appears that you want to run Tasks 1 - 3 to execute synchronously. So, you might as well do:

Task1();
Task2();
Task3();

If you want to offload the execution of these tasks to another thread, you can do:

static void RunTasks()
{
    Task1();
    Task2();
    Task3();
}

static void Main()
{
   new Thread(RunTasks).Start();
}

If you really wanted each task to run on a separate thread, and wait for the previous task to finish, you can use the Thread.Join method.

EDIT:

Since you really want to use wait-handles to accomplish this, take a look at the ManualResetEvent class.

Notifies one or more waiting threads that an event has occurred.

Call the WaitOne method on it to wait on the event, and the Set method to signal it.

Example (horribly contrived code):

var afterT1Event = new ManualResetEvent(false);
var afterT2Event = new ManualResetEvent(false);

Thread t1 = new Thread(() => { Task1(); afterT1Event.Set(); });
Thread t2 = new Thread(() => { afterT1Event.WaitOne(); Task2(); afterT2Event.Set(); });
Thread t3 = new Thread(() => { afterT2Event.WaitOne(); Task3(); });

t1.Start();
t2.Start();
t3.Start();

Upvotes: 4

Robin Salih
Robin Salih

Reputation: 547

If you want to use WaitHandles to acheive these then you could do the following:

declare the following two fields:

static ManualResetEvent handle1 = new ManualResetEvent(false);
static ManualResetEvent handle2 = new ManualResetEvent(false);

then at the end of Task1, add this:

    handle1.Set();

at the beginning of Task2, add:

    handle1.WaitOne();

then at the end, add

    handle2.Set();

then finally at the beginning of Task3 add

    handle2.WaitOne();

Upvotes: 2

Cole W
Cole W

Reputation: 15293

You could use ManualResetEvents and WaitHandle.WaitAny. Basically when one thread is done you would notify the other thread by using a ManualResetEvent (ManualResetEvent.Set()).

ManualResetEvent threadFinished = new ManualResetEvent(false);

//You would set this in the thread that has finished
threadFinished.Set()

//You would use this in the thread that you want to wait for this event to be signalled
int nWait = WaitHandle.WaitAny(new ManualResetEvent[] { threadFinished }, 10, true);

//if yes stop thread
if (nWait == 0)
{
    //Thread is finished
}

Upvotes: 0

Stuart
Stuart

Reputation: 66882

This feels very artificial, almost like homework...

... but basically you can use Join on a thread to wait for it.

Or the old msdn tutorial/example is very reasonable on this: http://msdn.microsoft.com/en-us/library/aa645740(VS.71).aspx

Upvotes: 1

Related Questions