mar*_*adi 2 c# multithreading thread-safety visual-studio
我想在线程列表中运行具有不同值的类.像这样 :
int index = 0;
foreach (TreeNode nd in tvew.Nodes[0].Nodes)
{
threadping[index] = new Thread(delegate()
{ this.Invoke(new DelegateClientState(InvokeCheckNetworkState), new object[] {nd}); });
threadping[index].Name = nd.Name;
threadping[index].IsBackground = true;
threadping[index].Start();
index++;
}
Run Code Online (Sandbox Code Playgroud)
但是当我调试代码时,我看到class参数只是最后一个值.我的意思是当我通过线程类时,我看到每次该类运行输入参数的值是最后一个线程的最后一个值.
任何人都可以告诉我为什么?
这是因为nd变量是在闭包中捕获的.当线程运行时,它们都引用相同的TreeNode实例,即分配给的最后一个实例nd.要修复,请使用在范围内不会更改的单独变量:
foreach (TreeNode nd in tvew.Nodes[0].Nodes)
{
var current = nd;
threadping[index] = new Thread(delegate()
{ this.Invoke(new DelegateClientState(InvokeCheckNetworkState), new object[] {current}); });
Run Code Online (Sandbox Code Playgroud)
如果我们得到编译器技术,这是因为编译器生成一个包含你的循环变量的匿名类,以使其可供线程委托访问.这是预期的行为,但是当你第一次碰到它时可能有点违反直觉.
有关闭包和变量捕获的更长解释,请参阅Jon Skeet文章中的Captured Variables部分(底部)或Eric Lippert的这篇文章.这通常被称为"访问修改后的闭包"错误.如果您在StackOverflow或Google上搜索该术语,您将获得大量的点击来解释它.
| 归档时间: |
|
| 查看次数: |
426 次 |
| 最近记录: |