Question: I'm working on the small SSHClient. I have a list of clients that are connected to different computers. I have a script that I want to run on those computers. I want to run it parallel in different threads.
I got inspired here:
[Stackoverflow - threads](https://stackoverflow.com/questions/2528907/c-sharp-spawn-multiple-threads-for-work-then-wait-until-all-finished)

Here is my piece of code:

```
 int toProcess, count = 0;
        ManualResetEvent resetEvent = new ManualResetEvent(false);
        toProcess = count = clients.Count;
        for (int i = 0; i < count; i++)
        {
                new Thread(delegate()
                {
                    var cmd = clients[i].RunCommand("./script.sh");
                    res += cmd.Result;
                    if (Interlocked.Decrement(ref toProcess) == 0)
                        resetEvent.Set();
                }).Start();
        }
        resetEvent.WaitOne();

        //do something

```

To me this code looks OK. But sometimes (actually it's in most cases) it happens that after the program goes correctly out of for loop, it gets correctly to the line `resetEvent.WaitOne();` but after, instead of waiting for all threads to finish and continue to proceed the rest of the code, it goes again to new Thread(delegate()... part of the code and since a variable i is already 2(in case there are two clients in the list of clients) I get an error:

> 
> Index was out of range. Must be non-negative and less than the size of
>  the collection.
> 
> 
> 

I wanted to ask how it is possible that it creates another thread although the for loop is finished. And how to avoid that?

Thank you

Answer: 
This is messy, in my opinion. I suggest using `Parallel.For` instead:

```
 int toProcess, count = 0;
 toProcess = count = clients.Count;
 object locker = new object();
 Parallel.For(0, count, i =>
 {
     var cmd = clients[i].RunCommand("./script.sh");
     lock(locker) res += cmd.Result;
 });

```

See this link: [Parallel.For](http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.for.aspx).
You can use a parallel linq query and aggregate its results via [Sum](http://msdn.microsoft.com/en-us/library/system.linq.enumerable.sum.aspx) method:

```
var totalResult = (from i in Enumerable.Range(0, client.Count).AsParallel()
                   let cmd = clients[i].RunCommand("./script.sh")
                   select cmd.Result).Sum();

```

With [AsParallel](http://msdn.microsoft.com/en-us/library/ee835374.aspx) method we create as many threads as we can and with Sum method we run the linq query and fetch each result for summing them up