2012-11-22 39 views
3

我在並行調用中做錯了什麼?迭代通過每個枚舉值需要並行

static void Main(string[] args) 
{ 
    TasteAll<HotCupOf>(TurnCoffeeVenMachineOn); 
} 

public static void TasteAll<Mode>(Action<Mode> Make) 
{ 
    foreach (Mode mode in Enum.GetValues(typeof(Mode))) 
    { 
     Task.Factory.StartNew(() => Make(mode)); 
     //Make(mode); //<-- Works Fine with normal call 
    } 
    Console.ReadLine(); 
} 

enum HotCupOf 
{ 
    Black, 
    Latte, 
    Cappuccino, 
    Mocha, 
    Americano, 
    Espresso, 
    Chocolate, 
    Tea 
} 

public static void TurnCoffeeVenMachineOn(HotCupOf SelectedDrink) 
{ 
    Console.WriteLine(SelectedDrink); 
} 

回答

5

您已經關閉了循環變量。您開始的每個任務都有一個對同一個閉合的變量的引用,這個變量在迭代集合時發生變化。

你需要的東西是這樣的:

public static void TasteAll<Mode>(Action<Mode> Make) 
{ 
     foreach (Mode mode in Enum.GetValues(typeof(Mode))) 
     { 
      Mode localMode = mode; 
      Task.Factory.StartNew(() => Make(localMode)); 
      //Make(mode); //<-- Works Fine with normal call 
     } 
    Console.ReadLine(); 
} 

用C#5,現在循環變量在語義上是內循環塊的,所以這是不必要的。有關其他討論,請參閱Eric Lippert的blog

+1

感謝您給我的第一個鏈接,我已經訪問並嘗試過: 'Mode CurrMode = mode;'then' Task.Factory.StartNew(()=> Make(CurrMode));' – LoneXcoder

1

如果你想循環阻塞,你也可以考慮使用Parallel.ForEach來解決這個問題。它使用分區程序將您的集合分發到工作項目中,然後以比每次迭代創建新的Task更高效的方式執行它們。這確實取決於你的呼叫有多沉重,而且迭代越多越好。

public static void TasteAll<Mode>(Action<Mode> Make) 
{ 
     Parallel.ForEach(Enum.GetValues(typeof(Mode)), mode => 
     { 
      Mode localMode = mode; 
      Make(mode); 
     }); 

    Console.ReadLine(); 
} 
+2

'Parallel.ForEach(Enum .GetValues(typeof運算(模式))'應'Parallel.ForEach((模式[])Enum.GetValues(typeof運算(模式))'然後,你不必'模式localMode =模式;'作爲類型是已經!爲'mode'定義 –

+0

謝謝。「邁克·德克勒克」爲「(模式[])」 - ICH正是尋找這個 – Stone

2

一個例子:

enum Gender{ 
     male, 
     female 
    }   

    Parallel.ForEach((Gender[])Enum.GetValues(typeof(Gender)), gender=> 
       { 
        Console.WriteLine(gender.ToString()) // example: code goes here 
       }); 

含義: 對於每個性別的性別,之間{}異步執行的代碼。

+0

代碼的說明會加強這方面的問題的答案也:它是如何從現有的答案是不同的。 ? – jAC

+0

@JanesAbouChleih:我從邁克·德克勒克的答案代碼davenewza的職位是什麼,他說是我在乾淨的形式最好的答案,我認爲它應該得到它自己也回答了我自己的參考作用中。在enum上並行。 –

+0

@JanesAbouChleih:我添加了一個例子 –