Connecting Tech Pros Worldwide Forums | Help | Site Map

Multi-Threading using Thread Pool C#

Newbie
 
Join Date: Jun 2008
Location: Indiana
Posts: 12
#1: Oct 14 '09
I have some code below which Queues up Worker Items... The only thing it doesn't do is wait for the application to finish executing it. Any ideas on how I can get the application wait for all these Console.Writelines to actually display on the screen? It exits out before it's finished.

Expand|Select|Wrap|Line Numbers
  1.  
  2. using System;
  3. using System.Threading;
  4.  
  5. namespace ThreadPoolTest
  6. {
  7.     class Program
  8.     {
  9.         private static int numBusy = 10000;
  10.         private const int NumThreads = 10000;
  11.         private static ManualResetEvent doneEvent;
  12.  
  13.         private static void Main(string[] args)
  14.         {
  15.             ThreadPool.SetMinThreads(100, 100);
  16.             doneEvent = new ManualResetEvent(false);
  17.             for (int s = 0; s < NumThreads; s++)
  18.             {
  19.                 ThreadPool.QueueUserWorkItem(
  20.                     new WaitCallback(DoWork), (object)s);
  21.             }
  22.             doneEvent.WaitOne();
  23.             Console.WriteLine("DONE");
  24.         }
  25.  
  26.         private static void DoWork(object o)
  27.         {
  28.             try
  29.             {
  30.  
  31.                 // do work here
  32.                 int index = (int)o;
  33.                 Console.WriteLine("Index: {0} Numbusy {1}: ", index, numBusy);
  34.                 //Thread.Sleep(100);
  35.                 //Console.WriteLine("DONE: {0} Numbusy {1}: ", index, numBusy);
  36.  
  37.             }
  38.             catch
  39.             {
  40.                 // error handling goes here
  41.             }
  42.             finally
  43.             {
  44.                 if (Interlocked.Decrement(ref numBusy) == 0)
  45.                 {
  46.                     doneEvent.Set();
  47.                 }
  48.             }
  49.         }
  50.     }
  51. }
  52.  
  53.  
  54.  
best answer - posted by ssouhrada
I have tried doing that but it will get the Console.Readline(); prior to actually executing all of the statements. The point is also to not have to require user interaction as I'm building an app that would hopefully not require supervision and could be scheduled to run. I did end up finding an answer on another post. Here is the code that ended up working as desired:


Expand|Select|Wrap|Line Numbers
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Threading;
  5. namespace ThreadPoolWaitForAllThread
  6. {
  7.     class Program
  8.     {
  9.         static void Main(string[] args)
  10.         {
  11.             List<ManualResetEvent> events = new List<ManualResetEvent>();
  12.             ThreadPool.SetMinThreads(500, 500);
  13.             for (int i = 0; i < 100000; i++)
  14.             {
  15.                 ThreadPoolObj obj = new ThreadPoolObj();
  16.                 obj.ObjectID = i;                
  17.                 obj.signal = new ManualResetEvent(false);
  18.                 events.Add(obj.signal);
  19.                 WaitCallback callback = new WaitCallback(ThreadFunction);
  20.                 ThreadPool.QueueUserWorkItem(callback, obj);
  21.             }
  22.             WaitForAll(events.ToArray());
  23.             Console.WriteLine("Completed");
  24.             Console.ReadLine();
  25.  
  26.  
  27.  
  28.  
  29.         }
  30.         static bool WaitForAll(ManualResetEvent[] events)
  31.         {
  32.             bool result = false;
  33.             try
  34.             {
  35.                 if (events != null)
  36.                 {
  37.                     for (int i = 0; i < events.Length; i++)
  38.                     {
  39.                         events[i].WaitOne();
  40.                     }
  41.                     result = true;
  42.                 }
  43.             }
  44.             catch
  45.             {
  46.                 result = false;
  47.             }
  48.             return result;
  49.         }
  50.         static void ThreadFunction(object threadobj)
  51.         {
  52.             ThreadPoolObj obj = threadobj as ThreadPoolObj;
  53.             if (obj != null)
  54.             {
  55.                 Console.WriteLine(obj.ObjectID.ToString());
  56.                 Thread.Sleep(2000); // Just Wait To Show Syncronization 
  57.                 obj.signal.Set();
  58.             }
  59.         }
  60.     }
  61.     class ThreadPoolObj
  62.     {
  63.         public int ObjectID;
  64.         public ManualResetEvent signal;
  65.     }
  66. }
  67.  
  68.  
  69.  
Expert
 
Join Date: Jun 2008
Location: Pretoria, South Africa
Posts: 410
#2: Oct 15 '09

re: Multi-Threading using Thread Pool C#


Hi

If I understand this correctly, you want to be able to read the output before the application exits? If so:

Expand|Select|Wrap|Line Numbers
  1. Console.ReadLine();
Will fix that problem. This will cause the application to be idle until the <ENTER> key is pressed.
Newbie
 
Join Date: Jun 2008
Location: Indiana
Posts: 12
#3: Oct 15 '09

re: Multi-Threading using Thread Pool C#


I have tried doing that but it will get the Console.Readline(); prior to actually executing all of the statements. The point is also to not have to require user interaction as I'm building an app that would hopefully not require supervision and could be scheduled to run. I did end up finding an answer on another post. Here is the code that ended up working as desired:


Expand|Select|Wrap|Line Numbers
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Threading;
  5. namespace ThreadPoolWaitForAllThread
  6. {
  7.     class Program
  8.     {
  9.         static void Main(string[] args)
  10.         {
  11.             List<ManualResetEvent> events = new List<ManualResetEvent>();
  12.             ThreadPool.SetMinThreads(500, 500);
  13.             for (int i = 0; i < 100000; i++)
  14.             {
  15.                 ThreadPoolObj obj = new ThreadPoolObj();
  16.                 obj.ObjectID = i;                
  17.                 obj.signal = new ManualResetEvent(false);
  18.                 events.Add(obj.signal);
  19.                 WaitCallback callback = new WaitCallback(ThreadFunction);
  20.                 ThreadPool.QueueUserWorkItem(callback, obj);
  21.             }
  22.             WaitForAll(events.ToArray());
  23.             Console.WriteLine("Completed");
  24.             Console.ReadLine();
  25.  
  26.  
  27.  
  28.  
  29.         }
  30.         static bool WaitForAll(ManualResetEvent[] events)
  31.         {
  32.             bool result = false;
  33.             try
  34.             {
  35.                 if (events != null)
  36.                 {
  37.                     for (int i = 0; i < events.Length; i++)
  38.                     {
  39.                         events[i].WaitOne();
  40.                     }
  41.                     result = true;
  42.                 }
  43.             }
  44.             catch
  45.             {
  46.                 result = false;
  47.             }
  48.             return result;
  49.         }
  50.         static void ThreadFunction(object threadobj)
  51.         {
  52.             ThreadPoolObj obj = threadobj as ThreadPoolObj;
  53.             if (obj != null)
  54.             {
  55.                 Console.WriteLine(obj.ObjectID.ToString());
  56.                 Thread.Sleep(2000); // Just Wait To Show Syncronization 
  57.                 obj.signal.Set();
  58.             }
  59.         }
  60.     }
  61.     class ThreadPoolObj
  62.     {
  63.         public int ObjectID;
  64.         public ManualResetEvent signal;
  65.     }
  66. }
  67.  
  68.  
  69.  
Reply