2012-01-06 11 views
0

をロック通常、私はそれらの間の共有オブジェクトのロックを必要とするが、今、私は最後にTask(TResult)クラスとマージがよりよい解決策である場合には不思議?最後にマージしてC#TPL私は、私の並列タスクからの結果をマージするための最良の方法は何か疑問に思って.NET 4.0でのタスク並列ライブラリの私の使用の際には、タスクの結果と、それを移入対タスク間の共有オブジェクト(TResult)タスク

public MyObject DoWork() 
{ 
    var result = new MyObject(); 
    var resultLock = new object(); 
    var taskArray = new Task[this._objects.Length]; 
    for (var i = 0; i < taskArray.Length; i++) 
    { 
     taskArray[i] = new Task((obj) => 
      { 
       var _o = obj as AnObject; 
       var tmpResult = _o.DoTaskWork(); 
       lock (resultLock) 
        result.Add(tmpResult); 
      }, this._objects[i]); 
    } 
    Task.WaitAll(taskArray); 
    return result; 
} 

とTPL:ロック付き

TPL:私は私が考える二つのアプローチがあります下に

public MyObject DoWork() 
{ 
    var taskArray = new Task<String>[this._objects.Length]; 
    for (var i = 0; i < taskArray.Length; i++) 
    { 
     taskArray[i] = new Task<String>((obj) => 
     { 
      var _o = obj as AnObject; 
      return _o.DoTaskWork(); 
     }, this._objects[i]); 
    } 
    Task<String>.WaitAll(taskArray); 
    var result = new MyObject(); 
    for (var i = 0; i < taskArray.Length; i++) 
     result.Add(taskArray[i].Result); 
    return result; 
} 

が正しいか間違っている溶液または何がありますパラレルLINQを使用してのベストプラクティスは、(並列タスクからマージした結果と、他の可能な解決策は最も歓迎されている)

答えて

2

(あなたのためのすべての厄介なものをしている)、あなたはこれを沸騰させることができ

var workResults = _objects.AsParallel().Select(DoTaskWork); 
foreach(var r in workResults) 
{ 
    result.Add(r); 
} 
+0

こんにちは、私は本当に提案された解決策、単純なLINQ'edが好きですが、私はタスクライブラリを使用する場合、何が望ましいだろう! – aweis

+0

その場合、私は、同時コレクション(http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx)のいずれかを使用してタスクの本体からまっすぐに追加します。 PLinqがTPLをフードの下で使用していることを忘れないでください。 – spender

+0

さて、ConcurrentDictionaryは非常にうまくいくものです。 PLINQはどのように行ってない私は、多くの場合、データ構造を照会するLINQを使用すると、時間との関係で高価であることを読んだことがあるので、時間が非常に重要な要因になったときに、いくつかのアップ/ダウン側は、PLINQにあるのでしょうか? – aweis

関連する問題