2012-01-06 42 views
0

在我使用.NET 4.0任務並行庫我想知道什麼是合併從我的並行任務結果的最佳方式的結果填充它,通常我會要求他們之間的共享對象上的鎖,但現在我想知道如果Task(TResult)類和合並的到底是一個更好的解決方案?下面我有兩種方法,我認爲:C#TPL鎖定任務之間共享對象VS與任務(TResult)任務

TPL與鎖:

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,並在最後的合併:

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 2012-01-06 09:19:27

+0

在這種情況下,我會使用併發集合中的一個(http://msdn.microsoft.com/en-us/library/system.collections.concurrent.aspx),並從任務體直接添加到它。不要忘記,PLinq在引擎蓋下使用TPL。 – spender 2012-01-06 09:25:18

+0

好的,ConcurrentDictionary將會非常適合。 PLINQ是如何執行的,因爲我經常讀到使用LINQ查詢數據結構與時間相關的代價很高,PLINQ中是否存在一些向上/向下的方面,而時間成爲一個非常重要的因素? – aweis 2012-01-06 09:32:23