2014-08-28 73 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?