【发布时间】:2012-10-08 01:08:50
【问题描述】:
我正在开发小型 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(); 行但之后,而不是等待所有线程完成并继续执行其余的代码,它再次进入 new Thread(delegate()... 部分代码,因为变量 i 已经是 2(如果客户端列表中有两个客户端)我收到错误:
索引超出范围。必须是非负数且小于 集合。
我想问一下,尽管 for 循环已经完成,它怎么可能创建另一个线程。又该如何避免呢?
谢谢
【问题讨论】:
-
似乎问题就在clients.Count附近。贴出更多相关代码
-
为什么不直接使用 Thread.Join?
-
... 或者您的
clients数组在循环运行期间被更改(来自其他线程?)? -
TPL(任务并行库)不会使这几乎成为一个单行吗?
-
变量
i被捕获。典型的闭包问题。
标签: c# multithreading