Optimize Implementation - Wait for all threads using LINQ In my program I read several information's about the system. I read each categories like CPU, memory, services, software and so on with a own thread. The main program have to wait for the longest thread.

To implement this, I use LINQ and the Join function from Thread.

Here is a small part from my code:

var culture = CultureInfo.CreateSpecificCulture("en-US");
var thread_list = new List&lt;Thread&gt;();
var c = new Computer();

var thrma = new Thread(() =&gt;
{
    c.Mainboard = new Mainboard().GetInformation();
});
thrma.CurrentUICulture = culture;
thrma.Start();
thread_list.Add(thrma);

var thrce = new Thread(() =&gt;
{
    c.ProcessorList = new CentralProcessingUnit().GetInformation();
});
thrce.CurrentUICulture = culture;
thrce.Start();
thread_list.Add(thrce);

...

var thrsvr = new Thread(() =&gt;
{
    DeviceService.ScanServices();
});
thrsvr.CurrentUICulture = culture;
thrsvr.Start();
thread_list.Add(thrsvr);

foreach (Thread t in thread_list)
{
    t.Join();
}

// Everyone is done!


Each hardware device is derived from the Hardware class.

What do you think about the solution? Is there a "nicer" or better implementation? I would like to use a function, because the code is very similar, but I'm not sure how to do it. Any idea?

Thanks for your advices.
It's better to use new asynchronous API since it provides more features for combining asynchronous tasks. 

Ideally Mainboard, CentralProcessingUnit and DeviceService should expose asynchronous API if a certain operation is not trivial, so (as you mentioned in comments you wrote them) I would implement asynchronous API for them first, e.g.:

public class Mainboard
{
    public Task&lt;string&gt; GetInformationAsync()
    {
        //TODO: extract long-term operation into Task. Try not to span extra threads here
    }
}


Then your method would look like:

Task.WaitAll(
    new Mainboard().GetInformationAsync().ContinueWith(task =&gt; c.Mainboard = task.Result),
    new CentralProcessingUnit().GetInformationAsync().ContinueWith(task =&gt; c.ProcessorList = task.Result),
    DeviceService.ScanServicesAsync());


If you decide not to implement async API the code can look like:

var c = new Computer();

Task.WaitAll(
    Task.Factory.StartNew(() =&gt; c.Mainboard = new Mainboard().GetInformation()),
    Task.Factory.StartNew(() =&gt; c.ProcessorList = new CentralProcessingUnit().GetInformation()),
    Task.Factory.StartNew(() =&gt; DeviceService.ScanServices()));