2011-01-11 9 views
3

私は問題がありますが、並列化されるのに適していると思いますが、C#でこれをどのように表現するかはわかりません。一般的にこのプログラムでは、いくつかのオブジェクトについて高価なテストを実行します。私は "私が進むことができる"ことを確認するためにテストしているので、それらのテストのいずれかが失敗するかどうかを知る必要があります。しかし、いずれかのテストが失敗した場合、全体が失敗し、関数全体が保守を受けるべきです。擬似コードで:いくつかの項目をテストし、おそらくベールする並列パターン

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

C#のどのパターンは、私がこれを表現し、それらをすべて並行してテストするのに最適でしょうか?これらのいずれかが失敗した場合、他のテストは終了しなければなりません。その結果は重要ではないからです。このうち@mquanポイントとして

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

が最も効率的ではないかもしれません:あなたはTPLに言及しているので

答えて

0

終了部分は、後で、または可能であれば、mquanderで述べたようにCancelationTokenの使用を無視することができます。

私はいくつかの汚いテストされていないpseudoishコードを捨てることを許可:

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のものは、それが終了していないので、私見

2

あなたはまた、PLINQを持っています。私は(私は100%確実ではないよ)以下がより速くなる可能性が想定しています

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

これは、ポスターの質問に対処していない「ビット」きれいに見えます1つのテストが失敗を通知したときの残りのテスト。 – mquander

+0

@mquander:そうです、代替案を追加します。 –

0

PLINQのアプローチは、このようになります:

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

並行して実行、シーケンスとしてGetGuysToProcessをキープし、見つけます最初の "悪い"もの。

関連する問題