Reputation: 5596
In my use of the Task Parallel Library in .net 4.0 I am wondering what is the best way to merge results from my parallel tasks, normally i would require a lock on a shared object between them, but now i wondering if the Task(TResult)
class and merging at the end is a better solution? Below I have the two approaches i consider:
TPL with lock:
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;
}
And TPL with the merging at the end:
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;
}
Is there a right or wrong solution or what is a best practice (other possible solution to merging results from parallel tasks are most welcome)
Upvotes: 0
Views: 1866
Reputation: 120440
using Parallel LINQ (which does all the nasty stuff for you), you could boil this down to a single line or so:
var workResults = _objects.AsParallel().Select(DoTaskWork);
foreach(var r in workResults)
{
result.Add(r);
}
Upvotes: 2