C#多线程用于工作然后等到所有完成

时间:2012-10-07 16:02:00

标签: c# multithreading

我正在研究小型SSHClient。我有一个连接到不同计算机的客户端列表。我有一个我想在这些计算机上运行的脚本。我想在不同的线程中并行运行它。 我在这里受到启发: Stackoverflow - threads

这是我的代码:

 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

对我来说,这段代码看起来不错。但有时候(实际上是在大多数情况下)它发生在程序正确地退出for循环后,它正确地到达行resetEvent.WaitOne();但是之后,而不是等待所有线程完成并继续继续其余代码,它再次转向新的Thread(delegate()...代码的一部分,因为变量i已经是2(如果客户列表中有两个客户端)我得到一个错误:

  

指数超出范围。必须是非负数且小于   集合。

我想问一下,虽然for循环已经完成,但它有可能创建另一个线程。以及如何避免这种情况?

谢谢

2 个答案:

答案 0 :(得分:3)

在我看来,这很混乱。我建议改为使用Parallel.For

 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;
 });

请参阅此链接:Parallel.For

答案 1 :(得分:0)

您可以使用并行linq查询并通过Sum方法汇总其结果:

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

使用AsParallel方法,我们可以创建尽可能多的线程,使用Sum方法运行linq查询并获取每个结果以将它们相加