2014-08-28 74 views
1

我开始与新的.net 4.5异步编程,我发现像下面的代码的情况:我有一个同步方法,但我想做几个调用,并使其并行运行。但是,在这段代码中,所有对sync方法的调用都以id = 10运行,我不知道为什么(可能我误解了这种新方法:)。异步任务与同步方法调用

class Program 
{ 
    static void Main(string[] args) 
    { 
     var tasks = new List<Task>(); 

     for (int i = 0; i < 10; i++) 
     { 
      var foo = new Foo(); 
      var fooTask = Task.Run(() => foo.FooNonAsyncMethod(i)); 
      tasks.Add(fooTask); 
     } 
     tasks.ForEach(t => t.Wait()); 

     Console.WriteLine("All Done!"); 

     Console.ReadLine(); 
    } 
} 

public class Foo 
{ 
    public void FooNonAsyncMethod(int id) 
    { 
     Console.WriteLine("Starting {0}", id); 

     Thread.Sleep(4000); 

     Console.WriteLine("Ending {0}", id); 
    } 
} 

// Output: 

// Starting 10 
// Starting 10 
// Starting 10 
// Starting 10 
// Ending 10 
// Starting 10 
// Starting 10 
// Ending 10 
// Ending 10 
// ... 
+2

的[可能重复有没有了C#重用的理由在foreach中的变量?](http://stackoverflow.com/questions/8898925/is-there-a-reason-for-cs-reuse-of-the-variable-in-a-foreach) – Yuriy 2014-08-28 12:00:02

+1

@Yuriy那个不是重复的,因为它在'foreach'这里是'for'。但肯定会回答这个问题。 – 2014-08-28 12:01:39

+2

使用'Task.WaitAll'而不是'tasks.ForEach(t => t.Wait());' – 2014-08-28 12:02:46

回答

4

这是因为只有1个变量i和lambda表达式绑定一个变量,而不是一个值。

您可以通过使用解决这个问题:

for (int i = 0; i < 10; i++) 
{ 
    int newI = i; 
    var foo = new Foo(); 
    var fooTask = Task.Run(() => foo.FooNonAsyncMethod(newI)); 
    tasks.Add(fooTask); 
} 

正如@Yuriy提到的,这个答案对这种特殊性更大量的信息:Is there a reason for C#'s reuse of the variable in a foreach?