2011-11-01 44 views
1

我一直在玩线程和任务(.net 4),并注意到一些奇怪的行为,当你启动多个线程,而不用等待几个毫秒之间的每个线程开始调用。启动多个线程,为什么你必须等待?

在运行时不输出下面的例子我所期待的:

1 
2 
1 
2 

而只是输出:

2 
2 
2 
2 

下面是我运行的代码。

public static void Main() 
{ 
    var items = new[] {"1", "2"}; 
    foreach (var item in items) 
    { 
     var thread = new Thread(() => Print(item));   
     thread.Start(); 
     //var task = Task.Factory.StartNew(() => Print(item));    
    } 
} 

static void Print(string something) 
{ 
    while (true) 
    { 
    Console.WriteLine(something); 
    Thread.Sleep(1000); 
    } 
} 

现在,当我打电话thread.Start(后Thread.sleep代码(50)),那么不仅会如预期的输出看

1 
2 
1 
2 

我的问题是:

  • 为什么当你在启动两个线程之间没有等待时,第一个线程是否松开了你最初使用的方法参数值?

即第一个线程以参数“1”启动,第二个线程以参数“2”启动,但是第一个线程的参数也变成了“2”?这没有任何意义,特别是因为Print()方法参数是字符串的值类型。

+0

谢谢你所有的答复。 – TheLegendaryCopyCoder

回答

5

谷歌“访问修改关闭”。发生了什么事是你的本地变量“item”正在调用print函数之前改变它的值。一个解决方案是在循环范围内创建一个新变量并为其分配项目。

2

该项目在您创建的线程由于c#关闭而启动时进行评估。给力的项目评估的另一种方法是引入一个变量,以便关闭将包括它像这样:

foreach (var item in items)  
     { 
      var closedItem = item; 
      var thread = new Thread(() => Print(closedItem));     
      thread.Start();  
     } 
0

我们展示线程开始的代码,你会发现,你不通过一个常量字符串,但一个引用变量,并且在调用那些Start方法之间,你可能正在改变这个变量。