If I were in your shoes, I'd be using a ThreadPool instead of manual threads. It handles all that stuff itself, and you don't have the overhead of creating and destroying threads. The code will probably be slightly more complex, because you'll need to use a ManualResetEvent instead of a simple Thread.Join() (see How can I accomplish ThreadPool.Join?), but you won't have to worry about creating too many threads, and it's nearly 40x faster.
Here's the class for a test I wrote comparing the two approaches:
class ThreadPoolVsThreads
{
private static readonly PerformanceMonitor threadPoolTest = new PerformanceMonitor("ThreadPoolTest");
private static readonly PerformanceMonitor threadTest = new PerformanceMonitor("ThreadTest");
private const int iterations = 100;
private const int threads = 10;
private static long somevalue;
public static void Test()
{
TestHelper.PerformTest(10, threadPoolTest, ThreadPoolTest);
TestHelper.PerformTest(10, threadTest, ThreadTest);
}
private static void ThreadPoolTest(int iteration)
{
for (int i = 0; i < iterations; i++)
{
var resetEvents = new ManualResetEvent[threads];
for (int j = 0; j < threads; j++)
{
var re = new ManualResetEvent(false);
resetEvents[j] = re;
ThreadPool.QueueUserWorkItem(o =>
{
somevalue++;
re.Set();
});
}
WaitHandle.WaitAll(resetEvents);
}
}
private static void ThreadTest(int iteration)
{
for (int i = 0; i < iterations; i++)
{
var threadArray = new Thread[threads];
for (int j = 0; j < threads; j++)
{
var thread = new Thread(o => somevalue++);
threadArray[j] = thread;
thread.Start();
}
for (int j = 0; j < threads; j++)
{
threadArray[j].Join();
}
}
}
}
And here's the output for five runs:
ThreadPoolTest action completed: iteration = 1, completionTime = 53, averageCompletionTime = 53.000
ThreadTest action completed: iteration = 1, completionTime = 2128, averageCompletionTime = 2128.000
ThreadPoolTest action completed: iteration = 2, completionTime = 42, averageCompletionTime = 47.500
ThreadTest action completed: iteration = 2, completionTime = 2149, averageCompletionTime = 2138.500
ThreadPoolTest action completed: iteration = 3, completionTime = 65, averageCompletionTime = 53.333
ThreadTest action completed: iteration = 3, completionTime = 2078, averageCompletionTime = 2118.333
ThreadPoolTest action completed: iteration = 4, completionTime = 72, averageCompletionTime = 58.000
ThreadTest action completed: iteration = 4, completionTime = 2137, averageCompletionTime = 2123.000
ThreadPoolTest action completed: iteration = 5, completionTime = 43, averageCompletionTime = 55.000
ThreadTest action completed: iteration = 5, completionTime = 2085, averageCompletionTime = 2115.400