类似的问题被问到here,但答案一般都与lambda表示法有关。我得到没有拉姆达类似的结果,所以我认为我会问一些澄清:线程启动的竞态条件
说我有这样的事情:
for (int i = 0; i < 5; i++)
(new Thread(new ThreadStart(delegate()
{
Console.WriteLine("Thread " + i);
}))).Start();
人们期望的输出如下:
Thread 0
Thread 1
Thread 2
Thread 3
Thread 4
现在我意识到线程并不是以任何特定的顺序开始的,所以我们假设上面的行可以以任何顺序出现。
但这不是发生了什么。 什么,而不是发生:
Thread 3
Thread 4
Thread 4
Thread 4
Thread 4
或类似的东西,这使我相信,而不是传递价值,如果我,它是通过基准。 (这很奇怪,因为int是一个值类型)。
做这样的事情:
for (int i = 0; i < 5; i++)
(new Thread(new ThreadStart(delegate()
{
int j = i;
Console.WriteLine("Thread " + j);
}))).Start();
并没有帮助,虽然我们已经取得了我的副本。我假设原因是它没有及时提供我的副本。
做这样的事情:
for (int i = 0; i < 5; i++)
{
(new Thread(new ThreadStart(delegate()
{
Console.WriteLine("Thread " + i);
}))).Start();
Thread.Sleep(50);
}
似乎解决这个问题,但它是非常不可取的,因为我们在每次迭代50ms的浪费,更何况一个事实,即如果计算机负载过重然后也许50ms可能是不够的。
这里是我当前的特定问题的例子:
Thread t = new Thread(new ThreadStart(delgate()
{
threadLogic(param1, param2, param3, param4);
}));
t.Start();
param1 = param2 = param3 = param4 = null;
有:
void threadLogic(object param1, object param2, object param3, object param4)
{
// Do some stuff here...
}
我想threadLogic()在它自己的线程中运行,但上面的代码给出了一个空参考例外。我认为这是因为在线程有机会开始之前将值设置为null。
再次,把Thread.Sleep(100)的作品,但它是从各个方面的可怕的解决方案。 你们对这种特殊类型的比赛状况有何建议?
见http://stackoverflow.com/questions/1930133/c-closures-why-is-the-loopvariable-captured-by-reference和http://stackoverflow.com/问题/ 1923577 /不同行为时,什么时候开始线程参数化线程启动vs匿名/ – nos 2011-02-08 23:31:41