简体   繁体   English

使用PLINQ返回null

[英]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. 我有一个IEnumerable的扩展方法,然后迭代集合,做它的业务,然后返回一个新的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. 我试图使用.AsParallel()。ForAll()来显着加速迭代(当然它应该这样做),但是当返回集合时,该集合中通常有一些对象是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. 编辑:要更清楚一点,在forall中有业务逻辑,修改属性等。有必要循环一个动作,而不是简单地选择一些东西。

The answer depends on what you mean by returning , because the ForAll method doesn't return anything. 答案取决于返回的含义,因为ForAll方法不会返回任何内容。 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!) ForAll方法不等待所有委托完成,因此在所有委托完成之前可以执行more code (并且您还需要在store result somewhere小心一点,因为它可能同时为多个委托运行!)

I think the code could be rewritten more elegantly using the Select method: 我认为使用Select方法可以更优雅地重写代码:

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. Where方法收集所有结果,当您迭代返回的IEnumerable ,它保证所有委托完成计算。

ForAll() doesn't perform a merge, and returns immediately. ForAll()不执行合并,并立即返回。 Parallel.ForEach() is probably the functionality you're looking for. Parallel.ForEach()可能是您正在寻找的功能。

ie instead of: 即代替:

collection.AsParallel().ForAll( t=>t.doWork() );

something like 就像是

Parallel.ForEach(collection.AsParallel(), t=>t.doWork());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM