returning null with PLINQ
i have an extension method for IEnumerable which then iterates through the collection, doing its business, and then returns an new IEnumerable.
I have tried to use PLINQ using .AsParallel().ForAll() which speeds up the iterations significantly (which of course it should do) however when the collection is returned, there are often a few objects in that collection that are null.
I'm assuming this may be because it is returning the 开发者_运维问答collection before all the 'business' has a chance to complete? if i debug and put in a breakpoint, there are no nulls.
is there some sort of 'wait for this operation to be completed' method that i should be using?
EDIT: to be a bit clearer, there is business logic in the forall, modifying properties etc. it's necessary to have an action looped, rather than simply selecting something.
The answer depends on what you mean by returning, because the ForAll
method doesn't return anything. It invokes the delegate you specify in parallel for all elements of the collection. I would suppose that your code looks like this:
data.AsParallel().ForAll(() => /* calculate and store result somewhere */);
// more code
The ForAll
method doesn't wait for all delegates to complete, so more code
can execute before all the delegates complete (and you also need to be careful in the store result somewhere
bit, because it may run concurrently for multiple delegates!)
I think the code could be rewritten more elegantly using the Select
method:
var res = data.AsParallel().Select(() => /* calculate the result */);
In this case, the delegate simply returns the result. The Where
method collects all the results and when you iterate over the returned IEnumerable
, it guarantees that all delegates finished calculating.
ForAll()
doesn't perform a merge, and returns immediately. Parallel.ForEach()
is probably the functionality you're looking for.
ie instead of:
collection.AsParallel().ForAll( t=>t.doWork() );
something like
Parallel.ForEach(collection.AsParallel(), t=>t.doWork());
精彩评论