Instead of starting a thread for each file name, queue the file names and then run three threads to process them. Or, since the main thread is now free, start two threads and let the main thread work on it too:
Queue<string> MyQueue; void MyProc() { string[] filenames = Directory.GetFiles(...); MyQueue = new Queue(filenames); // start two threads Thread t1 = new Thread((ThreadStart)ProcessQueue); Thread t2 = new Thread((ThreadStart)ProcessQueue); t1.Start(); t2.Start(); // main thread processes the queue, too! ProcessQueue(); // wait for threads to complete t1.Join(); t2.Join(); } private object queueLock = new object(); void ProcessQueue() { while (true) { string s; lock (queueLock) { if (MyQueue.Count == 0) { // queue is empty return; } s = MyQueue.Dequeue(); } ProcessFile(s); } }
Another option is to use a semaphore to control how many threads work:
Semaphore MySem = new Semaphore(3, 3); void MyProc() { string[] filenames = Directory.GetFiles(...); foreach (string s in filenames) { mySem.WaitOne(); ThreadPool.QueueUserWorkItem(ProcessFile, s); }
The first will work slightly better, because you do not have the overhead of starting and stopping the stream for each processed file name. The second, however, is much shorter and cleaner, and makes full use of the thread pool. You probably won't notice the difference in performance.
source share