用于测试多个物品并可能挽救的平行模式

时间:2011-01-11 17:05:50

标签: c# linq parallel-processing task-parallel-library

我有一个问题,我认为很适合并行,但我不确定如何在C#中表达这一点。通常在这个程序中,我将对几个对象进行昂贵的测试。我正在测试以确保"我可以前进",所以我需要知道这些测试中是否有任何失败。但是,如果任何测试失败,整个事情都会失败,整个功能应该保释。在伪代码中:

...
var guys = getGuysToProcess().ToList();
foreach (myGuys guy in guys) {
    if (!guy.TestForPossibleBadness())
      return false;
}

C#中的哪种模式最能让我表达并同时测试它们?如果其中任何一个失败,其他测试应该终止,因为它们的结果不重要。

3 个答案:

答案 0 :(得分:2)

既然你提到了TPL,你也有PLINQ:

// untested
bool ok = getGuysToProcess().AsParallel().All(g => !g.TestForPossibleBadness());

正如@mquan指出的那样,这可能不是最有效的。我假设以下内容可能更快(但我不是100%肯定):

// untested
bool ok = ! getGuysToProcess().AsParallel().Any(g => g.TestForPossibleBadness());

答案 1 :(得分:0)

PLINQ的方法是:

bool isBad = GetGuysToProcess().AsParallel().Any(g => g.TestForPossibleBadness());

将GetGuysToProcess保持为序列,并行运行并找到第一个“坏”序列。

答案 2 :(得分:0)

终止部分可以是忽略任务,之后,或者如果可能的话,使用mquander提到的CancelationToken。

请允许我扔掉一些脏的未经测试的伪代码:

var guyTask = new List<Task<bool>>();
foreach(var guy in guys){
  guyTask.Add(Task.Factory.StartNew(()=>guy.TestForPossibleBadness());
}
var guyTaskArr = guyTask.ToArray();
var running = true;
while(true){
  var i = Task.WaitAny(guyTaskArr);
  if (!guyTaskArr[i]))
     foreach(var guy in guyTask){
         if (!guy.IsCompleted || !guy.IsFaulted){
             guy.Cancel();
         }
     }
     return false;
  }else{
     guyTask.Remove(guyTaskArr[i]);
     if (guyTask.Count == 0) return true;
     guyTaskArr = guyTask.ToArray();
  }
}

PLINQ的东西看起来“有点”清洁恕我直言