Friday, March 26, 2010

Code: C# Simple Multithreading Example using ThreadPool

Below you will find a simple, complete code sample for multithreading in C# using the ThreadPool class.  This sample uses a simple counter to track the number of threads that are active to prevent the application from closing before all threads have completed.  Although there are other ways to force a method to wait for all threads to complete before exiting, using a static counter allows you to create a separate method to determine when the application is allowed to exit.  This is useful for handling OnStop events on windows services.  Within the StopProcessing() method you could also set a flag that would prevent your application from creating new threads.

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6.  
  7. namespace MultiThreadedApp
  8. {
  9.     class Program
  10.     {
  11.         static int _threadCounter = 0;
  12.  
  13.         static void Main(string[] args)
  14.         {
  15.             for (int i = 0; i < 10; i++)
  16.             {
  17.                 CreateThread(i);
  18.             }
  19.  
  20.             StopProcessing();
  21.  
  22.             Console.WriteLine("Finished");
  23.         }
  24.  
  25.         private static void CreateThread(int threadId)
  26.         {
  27.             Console.WriteLine("Creating Thread {0}", threadId);
  28.             MethodParameters newParameter = new MethodParameters();
  29.             newParameter.ThreadId = threadId;
  30.             newParameter.ThreadCreated = DateTime.Now;
  31.             Interlocked.Increment(ref _threadCounter);
  32.             ThreadPool.QueueUserWorkItem(new WaitCallback(LongRunningProcess), (object)newParameter);
  33.         }
  34.  
  35.         private static void LongRunningProcess(object input)
  36.         {
  37.             MethodParameters inputParams = (MethodParameters)input;
  38.             Random random = new Random(((MethodParameters)input).ThreadId);
  39.             Thread.Sleep(random.Next(500, 5000));
  40.             Console.WriteLine("Thread {0} complete in {1} seconds", inputParams.ThreadId,
  41.                 (DateTime.Now - inputParams.ThreadCreated).TotalSeconds);
  42.  
  43.             Interlocked.Decrement(ref _threadCounter);
  44.         }
  45.  
  46.         private static void StopProcessing()
  47.         {
  48.             Console.WriteLine("Waiting for {0} threads to complete", _threadCounter);
  49.             while (_threadCounter > 0)
  50.                 Thread.Sleep(500);
  51.         }
  52.  
  53.         private class MethodParameters
  54.         {
  55.             public DateTime ThreadCreated { get; set; }
  56.             public int ThreadId { get; set; }
  57.         }
  58.     }
  59. }

4 comments:

  1. thanks a lot for your code,
    i've learned a lot from it !
    thanks again !

    ReplyDelete
  2. I also learnt a lot from this tutorial, Many thanks!

    ReplyDelete
  3. There is a certain amount of overhead associated with starting and stopping a thread. In most of the applications, many threads would be idle most of the time or perform small operations and die quickly it is desirable to conserve resources by sharing already created threads. To do this, .NET provides a ThreadPool class that is easy to use.

    Prathap Kumar
    .Net Training

    ReplyDelete
  4. of all the multithreaded examples I've seen this afternoon, yours is the one that does what it says in a straightforward and clear manner for a non-threading dev. Thanks - I will meet my deadline!

    ReplyDelete