C# 正在更改的线程参数

C# 正在更改的线程参数,c#,.net,multithreading,.net-4.5,C#,.net,Multithreading,.net 4.5,启动多个线程时,我正在解析的id参数有时是错误的。以下是我的创业计划: for (int i = 0; i < _threadCount; i++) { Thread thread = new Thread(() => WorkerThread(i)); thread.Start(); _threads.Add(thread); } 此代码的输出为: [19:10:54] Thread start 3 [19:10:54] Thread start 9 [1

启动多个线程时,我正在解析的
id
参数有时是错误的。以下是我的创业计划:

for (int i = 0; i < _threadCount; i++)
{
    Thread thread = new Thread(() => WorkerThread(i));
    thread.Start();
    _threads.Add(thread);
}
此代码的输出为:

[19:10:54] Thread start 3
[19:10:54] Thread start 9
[19:10:54] Thread start 4
[19:10:54] Thread start 12
[19:10:54] Thread start 11
[19:10:54] Thread start 3
[19:10:54] Thread start 12
[19:10:54] Thread start 6
[19:10:54] Thread start 9
[19:10:54] Thread start 6
[19:10:54] Thread start 13
[19:10:54] Thread start 2
[19:10:54] Thread start 15
[19:10:54] Thread start 9
[19:10:54] Thread start 15
在我看来,这段代码应该使用唯一的
id
来创建每个线程,而不是像上面看到的那样重复

编译器信息:

平台目标:x64


目标框架:.NET Framework 4.5

在启动线程后,您应该小心不要意外地修改捕获的变量,如
i
,因为
i
共享的。
i
变量在循环的整个生命周期中引用相同的内存位置。解决方案是使用如下临时变量:

for (int i = 0; i < _threadCount; i++)
{
      var i1 = i;
      Thread thread = new Thread(() => WorkerThread(i1));
      thread.Start();
      _threads.Add(thread);
}
for(int i=0;i<\u threadCount;i++)
{
var i1=i;
线程线程=新线程(()=>WorkerThread(i1));
thread.Start();
_线程。添加(线程);
}

在这里阅读有关闭包的更多信息:

问题在于
i
变量在循环的生命周期中引用相同的内存位置。因此,每个线程调用一个变量,该变量的值在运行时可能会发生变化。解决方案是使用一个临时变量
int temp=i
。如前所述。

您的所有帖子都共享同一个变量。实际上,有人刚刚发布了一个类似的问题,下面是Eric Lippert关于该主题的链接文章。有趣。我本以为将值类型作为参数传递会自动完成这项工作。在函数调用和执行第一行之间是否有过渡期,在将其复制到WorkerThread的参数列表之前,我可以对其进行更改?谢谢您的回答和来源。是的,Jakotheshadows,我认为萨米人现在对我来说是有意义的。对WorkerThread的函数调用不一定在执行thread.Start()时发生;。它可能在循环过程中的任何时候发生,只有当WorkerThread在另一个线程中被调用时(可能比线程实例化的位置提前5次迭代),我才会得到计算结果并复制到参数列表中。这里的问题是,直到线程真正开始,我才得到评估。首先,
volatile
只能应用于类或结构字段,而不能应用于局部变量。其次,这不会改变这样一个事实,即在先前创建的线程运行之前,捕获的变量可能会递增。
for (int i = 0; i < _threadCount; i++)
{
      var i1 = i;
      Thread thread = new Thread(() => WorkerThread(i1));
      thread.Start();
      _threads.Add(thread);
}