2012-11-22 34 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:我添加了一个例子 –