I have what I assume is a pretty common threading scenario:
I would use ThreadPool.
Before you start running your jobs, create a ManualResetEvent and an int counter. Add each job to the ThreadPool, incrementing the counter each time.
At the end of each job, decrement the counter and when it hits zero, call Set() on the event.
In your main thread, call WaitOne() to wait for all of the jobs to be completed.