2012-03-08 153 views
6

this后,我被告知,下面的代码段遭受“关闭循环变量的令人震惊的行为”。关闭在C循环变量#

foreach (Canidate canidate in allCanidates) 
    { 
     Thread newThread = new Thread(delegate() 
     { 
      BusyWait(canidate); 
     }); 

     newThread.Start(); 
    } 

我把它切换到这一点:

foreach (Canidate canidate in allCanidates) 
     { 
      var can = canidate; 
      Thread newThread = new Thread(delegate() 
      {     
       BusyWait(can); 
      }); 

      newThread.Start(); 
     } 

但我的老板一直坚持认为它会从同样的问题受到影响。我用this链接来尝试解决这个问题。有人可以帮助我正确地解决问题,以便我的代码能够正确执行。这个问题对我来说都是新的,我不确定我是否完全理解它。

+17

你的老板是错的。 – 2012-03-08 22:28:35

+16

并有尖尖的头发。 – 2012-03-08 22:29:11

+0

任何人都可以解释这是为什么吗?我不知道我完全理解它。这两者之间的区别究竟是什么,因为他们看起来像是在做同样的事情。但是,当我运行它时,我知道它们不是。 – user489041 2012-03-08 22:33:00

回答

4

关闭变量,以后更改值是什么导致问题。

  • candidate改变每一个“圈”,围绕环和引起问题。
  • can是在环路周围新建立的每个“圈”,从不改变,并且不会造成问题。
+0

所以它失败了,因为候选人每改变一个“圈”,当线程实际执行时,它可能是当前候选值。由于循环很可能在线程启动之前完成,它通常是候选列表中的最后一项? – user489041 2012-03-08 22:46:58

+0

@ user489041准确地说,它会得到当前值,而不是它在包装时的值。一个不变的变量将会保持它的值(根据定义)并且不会引起问题,这就是为什么在循环中创建一个新变量将解决这个问题,它将超出范围并被重新创建而不是被改变。 – 2012-03-08 22:57:26