Spawn Multiple Threads for work then wait until all finished
just want some advice on "best practice" regarding multi-threading tasks.
as an example, we have a C# application that upon startup reads data from various "type" table in our database and stores the information in a collection which we pass around the application. this prevents us from hitting the database each time this information is required.
at the moment the application is reading data from 10 tables synchronously. i would really like to have the application read from each table in a different thread all running in parallel. the application would wait for all the threads to complete before continuing with the startup of the application.
i have looked into BackGroundWorker but just want some advice on accomplishing the above.
- Does the method sound logical in order to speed up the startup time of our application
- How can we best handle all the threads keeping in mind that each thread's work is independent of one another, we just need to wait for all the threads to complete before continuing.
i look forward to some answers
Solution 1:
My preference for this is to handle this via a single WaitHandle, and use Interlocked to avoid locking on a counter:
class Program
{
static void Main(string[] args)
{
int numThreads = 10;
ManualResetEvent resetEvent = new ManualResetEvent(false);
int toProcess = numThreads;
// Start workers.
for (int i = 0; i < numThreads; i++)
{
new Thread(delegate()
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
// If we're the last thread, signal
if (Interlocked.Decrement(ref toProcess) == 0)
resetEvent.Set();
}).Start();
}
// Wait for workers.
resetEvent.WaitOne();
Console.WriteLine("Finished.");
}
}
This works well, and scales to any number of threads processing, without introducing locking.
Solution 2:
I like @Reed's solution. Another way to accomplish the same in .NET 4.0 would be to use a CountdownEvent.
class Program
{
static void Main(string[] args)
{
var numThreads = 10;
var countdownEvent = new CountdownEvent(numThreads);
// Start workers.
for (var i = 0; i < numThreads; i++)
{
new Thread(delegate()
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
// Signal the CountdownEvent.
countdownEvent.Signal();
}).Start();
}
// Wait for workers.
countdownEvent.Wait();
Console.WriteLine("Finished.");
}
}
Solution 3:
If you have more than 64 wait handles for an STA Thread as Mark says. you could create a list with your threads and wait for all to complete in a second loop.
//check that all threads have completed.
foreach (Thread thread in threadList)
{
thread.Join();
}