Synchronize the Execution of Multiple Threads Using a Monitor - CSharp Thread Asynchronous

CSharp examples for Thread Asynchronous:Synchronize

Description

Synchronize the Execution of Multiple Threads Using a Monitor

Demo Code


using System;/*  w  ww.j a  va2  s  .c  o  m*/
using System.Threading;
using System.Collections.Generic;

class MainClass
    {
        private static object consoleGate = new Object();

        private static Queue<string> workQueue = new Queue<string>();

        private static bool processWorkItems = true;

        private static void TraceMsg(string msg)
        {
            lock (consoleGate)
            {
                Console.WriteLine("[{0,3}/{1}] - {2} : {3}",
                    Thread.CurrentThread.ManagedThreadId,
                    Thread.CurrentThread.IsThreadPoolThread ? "pool" : "fore",
                    DateTime.Now.ToString("HH:mm:ss.ffff"), msg);
            }
        }

        private static void ProcessWorkItems()
        {
            string workItem = null;

            TraceMsg("Thread started, processing items from queue...");

            while (processWorkItems)
            {
                Monitor.Enter(workQueue);

                try
                {
                    if (workQueue.Count == 0)
                    {
                        TraceMsg("No work items, waiting...");

                        Monitor.Wait(workQueue);
                    }
                    else
                    {
                        workItem = workQueue.Dequeue();
                    }
                }
                finally
                {
                    Monitor.Exit(workQueue);
                }
                if (workItem != null)
                {
                    lock (consoleGate)
                    {
                        for (int i = 0; i < 5; i++)
                        {
                            TraceMsg("Processing " + workItem);
                            Thread.Sleep(200);
                        }
                    }

                    // Reset the status of the local variable.
                    workItem = null;
                }
            }

            // This will only be reached if processWorkItems is false.
            TraceMsg("Terminating.");
        }

        public static void Main()
        {
            TraceMsg("Starting worker threads.");

            lock (workQueue)
            {
                workQueue.Enqueue("Work Item 1");
            }

            for (int count = 0; count < 3; count++)
            {
                (new Thread(ProcessWorkItems)).Start();
            }

            Thread.Sleep(1500);
            TraceMsg("pulse one waiting thread.");

            lock (workQueue)
            {
                workQueue.Enqueue("Work Item 2.");

                Monitor.Pulse(workQueue);
            }

            Thread.Sleep(2000);

            TraceMsg("pulse three waiting threads.");

            lock (workQueue)
            {
                workQueue.Enqueue("Work Item 3.");
                Monitor.Pulse(workQueue);
                workQueue.Enqueue("Work Item 4.");
                Monitor.Pulse(workQueue);
                workQueue.Enqueue("Work Item 5.");
                Monitor.Pulse(workQueue);
            }

            Thread.Sleep(3500);

            TraceMsg("pulse all waiting threads.");
            lock (workQueue)
            {
                processWorkItems = false;
                Monitor.PulseAll(workQueue);
            }

            Thread.Sleep(1000);

        }
    }

Result


Related Tutorials