How much order do you need to impose on the threads? If you just need all of the work started in the loop to finish before the code continues, but you don't care about the order the work within the loop finishes, then calling Join is the answer. To add more detail to Kevin Kenny's answer, you should call Join outside the loop. This means you will need a collection to hold references to the threads you started:
// Start all of the threads.
List<Thread> startedThreads = new List<Thread>();
foreach (...) {
Thread thread = new Thread(new ThreadStart(MyMethod));
thread.Start();
startedThreads.Add(thread);
}
// Wait for all of the threads to finish.
foreach (Thread thread in startedThreads) {
thread.Join();
}
In contrast, if you called Join inside the loop, the result would basically be the same as not using threads at all. Each iteration of the loop body would create and start a thread but then immediately Join it and wait for it to finish.
If the individual threads produce some result (write a message in a log, for example) then the messages may still appear out of order because there's no coordination between the threads. It is possible to get the threads to output their results in order by coordinating them with a Monitor.