Friday, July 27, 2012

Thread Pool Example


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ThreadPoolTest
{
   
    class Program
    {
 
        private const int NumThreads = 3;
        private static int[] inputArray;
        private static double[] resultArray;
        private static ManualResetEvent[] resetEvents;
        private static void Main(string[] args)
        {
            inputArray = new int[NumThreads];
            resultArray = new double[NumThreads];
            // An object that allows one thread to signal another thread
            // when something happens. 
            // In the case of this code, we use these events to signal the main
            // thread that a work item has been completed.
            resetEvents = new ManualResetEvent[NumThreads];
            Random rand = new Random();
            for (int s = 0; s < NumThreads; s++)
            {
                inputArray[s] = rand.Next(1, 5000000);
                //ManualResetEvent with its signaled state initially set to false,
                // and then we queue the work item. 
                resetEvents[s] = new ManualResetEvent(false);
 
                // Well, we are saying that a thread in the thread pool should run
                // the method DoWork, with the argument s. Any method that you want 
                // to queue up for the thread pool to run needs to take one 
                // argument, an object, and return void. The argument will end up 
                // being whatever you passed in as the second argument to the 
                // QueueUserWorkItem call - and in this case is the 'index' of this 
                // work item (the index in the various arrays that it needs to work 
                // with). And it makes sense that the method would have to return 
                // void - because it isn't actually returning 'to' anything, it is 
                // running out there all on its own as a separate thread.
 
                ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), (object)s);
            }
            Console.WriteLine("Waiting...");
            // we hit the very important call WaitHandle.WaitAll(resetEvents). This 
            // causes the main thread to block here until all the ManualResetEvent  
            // objects in the resetEvents array signal. When all of them have 
            // signaled, that means that all the work units have been completed, and 
            // so we continue on and print out all the results. 
            WaitHandle.WaitAll(resetEvents);
            Console.WriteLine("And the answers are: ");
            for (int i = 0; i < NumThreads; i++)
                Console.WriteLine(inputArray[i] + " -> " + resultArray[i]);
        }
        private static void DoWork(object o)
        {
            int index = (int)o;
            for (int i = 1; i < inputArray[index]; i++)
                resultArray[index] = inputArray[index]*100;
            resetEvents[index].Set();
        }
    }
} 

No comments:

Post a Comment