我正在研究小型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循环已经完成,但它有可能创建另一个线程。以及如何避免这种情况?
谢谢
答案 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查询并获取每个结果以将它们相加