在C#中,如果我执行混淆线程的行为
for (int i = 0;i < 10;i++)
new Thread(() => Console.Write(i)).Start();
我很可能会获得0223557799,这是奇怪的,因为我是一个INT,我觉得应该在线程开始前被复制。
在C#中,如果我执行混淆线程的行为
for (int i = 0;i < 10;i++)
new Thread(() => Console.Write(i)).Start();
我很可能会获得0223557799,这是奇怪的,因为我是一个INT,我觉得应该在线程开始前被复制。
瓶盖是你的问题就在这里。
基本上,当你需要它时,它会抓取它,而不是在你创建时创建(在循环中)。计算机速度非常快,到时候它已经改变了。它不能贯穿整个循环,但它贯穿了整个循环。
这里有一个修复:
for (int i = 0; i < 10; i++)
{
var n = i;
new Thread(() => Console.Write(n)).Start();
}
你拉姆达将被转换成一组,它将处理有指向到我的方法和上下文类的。
由于Start()
立即返回,i++
发生在线程有机会将i
打印到控制台之前。我相信,一个解决办法是建立在诚信的本地副本,然后打印:
for (int i = 0;i < 10;i++) {
int j = i;
new Thread(() => Console.Write(j)).Start();
}
基本上什么正在发生的事情是这样的:
你希望启动打印的i
值的线程。
线程开始。
的代码在线程操作得到,如果i
值。 请注意,我的值现在可以改变。
i
的值被印刷。但没有保证获得逻辑输出。
将i的值复制到另一个变量中,然后打印该值。其他答案提供了足够的样本代码。
我会使用内置的.NET并行支持Task Parallelism
您将不必担心如何管理它为你做的线程。
实施例的代码转换为并行库。
Parallel.For(0, 10, (i, state) =>
{
Console.WriteLine(i);
});
见埃里克利珀的[关闭了被认为是有害的循环变量(http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable -considered-harmful.aspx)。它主要讨论'foreach',但'for'和(根据顶部注释)存在相同的情况,'foreach'已被更改,但'for'不会(可能) –
而且“我认为它应该是在线程启动之前复制“。你认为你在做什么或谁是副本? –