2 // ParallelEnumerable.cs
5 // Jérémie "Garuma" Laval <jeremie.laval@gmail.com>
7 // Copyright (c) 2010 Jérémie "Garuma" Laval
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 using System
.Threading
;
30 using System
.Collections
;
31 using System
.Collections
.Generic
;
32 using System
.Collections
.Concurrent
;
33 using System
.Linq
.Parallel
;
34 using System
.Linq
.Parallel
.QueryNodes
;
38 public static class ParallelEnumerable
40 #region Range & Repeat
41 public static ParallelQuery
<int> Range (int start
, int count
)
43 if (int.MaxValue
- start
< count
- 1)
44 throw new ArgumentOutOfRangeException ("count", "start + count - 1 is larger than Int32.MaxValue");
46 throw new ArgumentOutOfRangeException ("count", "count is less than 0");
48 return (new RangeList (start
, count
)).AsParallel ();
51 public static ParallelQuery
<TResult
> Repeat
<TResult
> (TResult element
, int count
)
54 throw new ArgumentOutOfRangeException ("count", "count is less than 0");
56 return (new RepeatList
<TResult
> (element
, count
)).AsParallel ();
61 public static ParallelQuery
<TResult
> Empty
<TResult
> ()
63 return Repeat
<TResult
> (default (TResult
), 0);
68 public static ParallelQuery
<TSource
> AsParallel
<TSource
> (this IEnumerable
<TSource
> source
)
71 throw new ArgumentNullException ("source");
73 /* Someone might be trying to use AsParallel a bit too much, if the query was in fact
74 * already a ParallelQuery, just cast it
76 ParallelQuery
<TSource
> query
= source
as ParallelQuery
<TSource
>;
78 return query
?? new ParallelQuery
<TSource
> (new QueryStartNode
<TSource
> (source
));
81 public static ParallelQuery
<TSource
> AsParallel
<TSource
> (this Partitioner
<TSource
> source
)
84 throw new ArgumentNullException ("source");
86 /* Someone might be trying to use AsParallel a bit too much, if the query was in fact
87 * already a ParallelQuery, just cast it
89 ParallelQuery
<TSource
> query
= source
as ParallelQuery
<TSource
>;
91 return query
?? new ParallelQuery
<TSource
> (new QueryStartNode
<TSource
> (source
));
94 public static ParallelQuery
AsParallel (this IEnumerable source
)
97 throw new ArgumentNullException ("source");
99 /* Someone might be trying to use AsParallel a bit too much, if the query was in fact
100 * already a ParallelQuery, just cast it
102 ParallelQuery query
= source
as ParallelQuery
;
104 return query
?? new ParallelQuery
<object> (new QueryStartNode
<object> (source
.Cast
<object> ()));
107 public static IEnumerable
<TSource
> AsEnumerable
<TSource
> (this ParallelQuery
<TSource
> source
)
110 throw new ArgumentNullException ("source");
112 return source
.AsSequential ();
115 public static IEnumerable
<TSource
> AsSequential
<TSource
> (this ParallelQuery
<TSource
> source
)
118 throw new ArgumentNullException ("source");
120 return source
.Node
.GetSequential ();
124 #region AsOrdered / AsUnordered
125 public static ParallelQuery
<TSource
> AsOrdered
<TSource
> (this ParallelQuery
<TSource
> source
)
128 throw new ArgumentNullException ("source");
130 return new ParallelQuery
<TSource
> (new QueryAsOrderedNode
<TSource
> (source
.Node
));
133 public static ParallelQuery
<TSource
> AsUnordered
<TSource
> (this ParallelQuery
<TSource
> source
)
136 throw new ArgumentNullException ("source");
138 return new ParallelQuery
<TSource
> (new QueryAsUnorderedNode
<TSource
> (source
.Node
));
141 public static ParallelQuery
AsOrdered (this ParallelQuery source
)
144 throw new ArgumentNullException ("source");
146 return source
.TypedQuery
.AsOrdered ();
151 public static ParallelQuery
<TSource
> WithExecutionMode
<TSource
> (this ParallelQuery
<TSource
> source
,
152 ParallelExecutionMode executionMode
)
155 throw new ArgumentNullException ("source");
157 return new ParallelQuery
<TSource
> (new ParallelExecutionModeNode
<TSource
> (executionMode
, source
.Node
));
160 public static ParallelQuery
<TSource
> WithCancellation
<TSource
> (this ParallelQuery
<TSource
> source
,
161 CancellationToken cancellationToken
)
164 throw new ArgumentNullException ("source");
166 return new ParallelQuery
<TSource
> (new CancellationTokenNode
<TSource
> (cancellationToken
, source
.Node
));
169 public static ParallelQuery
<TSource
> WithMergeOptions
<TSource
> (this ParallelQuery
<TSource
> source
,
170 ParallelMergeOptions mergeOptions
)
173 throw new ArgumentNullException ("source");
175 return new ParallelQuery
<TSource
> (new ParallelMergeOptionsNode
<TSource
> (mergeOptions
, source
.Node
));
178 public static ParallelQuery
<TSource
> WithDegreeOfParallelism
<TSource
> (this ParallelQuery
<TSource
> source
,
179 int degreeOfParallelism
)
181 if (degreeOfParallelism
< 1 || degreeOfParallelism
> 63)
182 throw new ArgumentException ("degreeOfParallelism is less than 1 or greater than 63", "degreeOfParallelism");
184 throw new ArgumentNullException ("source");
186 return new ParallelQuery
<TSource
> (new DegreeOfParallelismNode
<TSource
> (degreeOfParallelism
, source
.Node
));
189 internal static ParallelQuery
<TSource
> WithImplementerToken
<TSource
> (this ParallelQuery
<TSource
> source
,
190 CancellationTokenSource token
)
192 return new ParallelQuery
<TSource
> (new ImplementerTokenNode
<TSource
> (token
, source
.Node
));
197 public static ParallelQuery
<TResult
> Select
<TSource
, TResult
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, TResult
> selector
)
200 throw new ArgumentNullException ("source");
201 if (selector
== null)
202 throw new ArgumentNullException ("selector");
204 return new ParallelQuery
<TResult
> (new QuerySelectNode
<TResult
, TSource
> (source
.Node
, selector
));
207 public static ParallelQuery
<TResult
> Select
<TSource
, TResult
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, int, TResult
> selector
)
210 throw new ArgumentNullException ("source");
211 if (selector
== null)
212 throw new ArgumentNullException ("selector");
214 return new ParallelQuery
<TResult
> (new QuerySelectNode
<TResult
, TSource
> (source
.Node
, selector
));
219 public static ParallelQuery
<TResult
> SelectMany
<TSource
, TResult
> (this ParallelQuery
<TSource
> source
,
220 Func
<TSource
, IEnumerable
<TResult
>> selector
)
222 return source
.SelectMany (selector
, (s
, e
) => e
);
225 public static ParallelQuery
<TResult
> SelectMany
<TSource
, TResult
> (this ParallelQuery
<TSource
> source
,
226 Func
<TSource
, int, IEnumerable
<TResult
>> selector
)
228 return source
.SelectMany (selector
, (s
, e
) => e
);
231 public static ParallelQuery
<TResult
> SelectMany
<TSource
, TCollection
, TResult
> (this ParallelQuery
<TSource
> source
,
232 Func
<TSource
, IEnumerable
<TCollection
>> collectionSelector
,
233 Func
<TSource
, TCollection
, TResult
> resultSelector
)
235 return new ParallelQuery
<TResult
> (new QuerySelectManyNode
<TSource
, TCollection
, TResult
> (source
.Node
,
240 public static ParallelQuery
<TResult
> SelectMany
<TSource
, TCollection
, TResult
> (this ParallelQuery
<TSource
> source
,
241 Func
<TSource
, int, IEnumerable
<TCollection
>> collectionSelector
,
242 Func
<TSource
, TCollection
, TResult
> resultSelector
)
244 return new ParallelQuery
<TResult
> (new QuerySelectManyNode
<TSource
, TCollection
, TResult
> (source
.Node
,
251 public static ParallelQuery
<TSource
> Where
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, bool> predicate
)
254 throw new ArgumentNullException ("source");
255 if (predicate
== null)
256 throw new ArgumentNullException ("predicate");
258 return new ParallelQuery
<TSource
> (new QueryWhereNode
<TSource
> (source
.Node
, predicate
));
261 public static ParallelQuery
<TSource
> Where
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, int, bool> predicate
)
264 throw new ArgumentNullException ("source");
265 if (predicate
== null)
266 throw new ArgumentNullException ("predicate");
268 return new ParallelQuery
<TSource
> (new QueryWhereNode
<TSource
> (source
.Node
, predicate
));
273 public static TSource Aggregate
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, TSource
, TSource
> func
)
276 throw new ArgumentNullException ("source");
278 throw new ArgumentNullException ("func");
280 return source
.Aggregate
<TSource
, TSource
, TSource
> ((Func
<TSource
>)null,
286 public static TAccumulate Aggregate
<TSource
, TAccumulate
> (this ParallelQuery
<TSource
> source
,
288 Func
<TAccumulate
, TSource
, TAccumulate
> func
)
291 throw new ArgumentNullException ("source");
293 throw new ArgumentNullException ("func");
295 return source
.Aggregate (seed
, func
, (e
) => e
);
298 public static TResult Aggregate
<TSource
, TAccumulate
, TResult
> (this ParallelQuery
<TSource
> source
,
300 Func
<TAccumulate
, TSource
, TAccumulate
> func
,
301 Func
<TAccumulate
, TResult
> resultSelector
)
304 throw new ArgumentNullException ("source");
306 throw new ArgumentNullException ("func");
307 if (resultSelector
== null)
308 throw new ArgumentNullException ("resultSelector");
310 TAccumulate accumulator
= seed
;
312 foreach (TSource
value in source
)
313 accumulator
= func (accumulator
, value);
315 return resultSelector (accumulator
);
318 public static TResult Aggregate
<TSource
, TAccumulate
, TResult
> (this ParallelQuery
<TSource
> source
,
320 Func
<TAccumulate
, TSource
, TAccumulate
> updateAccumulatorFunc
,
321 Func
<TAccumulate
, TAccumulate
, TAccumulate
> combineAccumulatorsFunc
,
322 Func
<TAccumulate
, TResult
> resultSelector
)
325 throw new ArgumentNullException ("source");
326 if (updateAccumulatorFunc
== null)
327 throw new ArgumentNullException ("updateAccumulatorFunc");
328 if (combineAccumulatorsFunc
== null)
329 throw new ArgumentNullException ("combineAccumulatorsFunc");
330 if (resultSelector
== null)
331 throw new ArgumentNullException ("resultSelector");
333 return source
.Aggregate (() => seed
, updateAccumulatorFunc
, combineAccumulatorsFunc
, resultSelector
);
336 public static TResult Aggregate
<TSource
, TAccumulate
, TResult
> (this ParallelQuery
<TSource
> source
,
337 Func
<TAccumulate
> seedFactory
,
338 Func
<TAccumulate
, TSource
, TAccumulate
> updateAccumulatorFunc
,
339 Func
<TAccumulate
, TAccumulate
, TAccumulate
> combineAccumulatorsFunc
,
340 Func
<TAccumulate
, TResult
> resultSelector
)
343 throw new ArgumentNullException ("source");
344 if (seedFactory
== null)
345 throw new ArgumentNullException ("seedFactory");
346 if (updateAccumulatorFunc
== null)
347 throw new ArgumentNullException ("updateAccumulatorFunc");
348 if (combineAccumulatorsFunc
== null)
349 throw new ArgumentNullException ("combineAccumulatorsFunc");
350 if (resultSelector
== null)
351 throw new ArgumentNullException ("resultSelector");
353 TAccumulate accumulator
= default (TAccumulate
);
355 ParallelExecuter
.ProcessAndAggregate
<TSource
, TAccumulate
> (source
.Node
, seedFactory
, updateAccumulatorFunc
, (list
) => {
356 accumulator
= list
[0];
357 for (int i
= 1; i
< list
.Count
; i
++)
358 accumulator
= combineAccumulatorsFunc (accumulator
, list
[i
]);
361 return resultSelector (accumulator
);;
366 public static void ForAll
<TSource
> (this ParallelQuery
<TSource
> source
, Action
<TSource
> action
)
369 throw new ArgumentNullException ("source");
371 throw new ArgumentNullException ("action");
373 ParallelExecuter
.ProcessAndBlock (source
.Node
, (e
, c
) => action (e
));
378 public static OrderedParallelQuery
<TSource
> OrderByDescending
<TSource
, TKey
> (this ParallelQuery
<TSource
> source
,
379 Func
<TSource
, TKey
> keySelector
,
380 IComparer
<TKey
> comparer
)
383 throw new ArgumentNullException ("source");
384 if (keySelector
== null)
385 throw new ArgumentNullException ("keySelector");
386 if (comparer
== null)
387 comparer
= Comparer
<TKey
>.Default
;
389 Comparison
<TSource
> comparison
= (e1
, e2
) => -comparer
.Compare (keySelector (e1
), keySelector (e2
));
391 return new OrderedParallelQuery
<TSource
> (new QueryOrderByNode
<TSource
> (source
.Node
, comparison
));
394 public static OrderedParallelQuery
<TSource
> OrderByDescending
<TSource
, TKey
> (this ParallelQuery
<TSource
> source
,
395 Func
<TSource
, TKey
> keySelector
)
397 return OrderByDescending (source
, keySelector
, Comparer
<TKey
>.Default
);
400 public static OrderedParallelQuery
<TSource
> OrderBy
<TSource
, TKey
> (this ParallelQuery
<TSource
> source
,
401 Func
<TSource
, TKey
> keySelector
)
403 return OrderBy (source
, keySelector
, Comparer
<TKey
>.Default
);
406 public static OrderedParallelQuery
<TSource
> OrderBy
<TSource
, TKey
> (this ParallelQuery
<TSource
> source
,
407 Func
<TSource
, TKey
> keySelector
,
408 IComparer
<TKey
> comparer
)
411 throw new ArgumentNullException ("source");
412 if (keySelector
== null)
413 throw new ArgumentNullException ("keySelector");
414 if (comparer
== null)
415 comparer
= Comparer
<TKey
>.Default
;
417 Comparison
<TSource
> comparison
= (e1
, e2
) => comparer
.Compare (keySelector (e1
), keySelector (e2
));
419 return new OrderedParallelQuery
<TSource
> (new QueryOrderByNode
<TSource
> (source
.Node
, comparison
));
424 public static OrderedParallelQuery
<TSource
> ThenBy
<TSource
, TKey
> (this OrderedParallelQuery
<TSource
> source
,
425 Func
<TSource
, TKey
> keySelector
)
427 return ThenBy (source
, keySelector
, Comparer
<TKey
>.Default
);
430 public static OrderedParallelQuery
<TSource
> ThenBy
<TSource
, TKey
> (this OrderedParallelQuery
<TSource
> source
,
431 Func
<TSource
, TKey
> keySelector
,
432 IComparer
<TKey
> comparer
)
435 throw new ArgumentNullException ("source");
436 if (keySelector
== null)
437 throw new ArgumentNullException ("keySelector");
438 if (comparer
== null)
439 comparer
= Comparer
<TKey
>.Default
;
441 Comparison
<TSource
> comparison
= (e1
, e2
) => comparer
.Compare (keySelector (e1
), keySelector (e2
));
443 return new OrderedParallelQuery
<TSource
> (new QueryOrderByNode
<TSource
> (source
.Node
, comparison
));
446 public static OrderedParallelQuery
<TSource
> ThenByDescending
<TSource
, TKey
> (this OrderedParallelQuery
<TSource
> source
,
447 Func
<TSource
, TKey
> keySelector
)
449 return ThenByDescending (source
, keySelector
, Comparer
<TKey
>.Default
);
452 public static OrderedParallelQuery
<TSource
> ThenByDescending
<TSource
, TKey
> (this OrderedParallelQuery
<TSource
> source
,
453 Func
<TSource
, TKey
> keySelector
,
454 IComparer
<TKey
> comparer
)
457 throw new ArgumentNullException ("source");
458 if (keySelector
== null)
459 throw new ArgumentNullException ("keySelector");
460 if (comparer
== null)
461 comparer
= Comparer
<TKey
>.Default
;
463 Comparison
<TSource
> comparison
= (e1
, e2
) => -comparer
.Compare (keySelector (e1
), keySelector (e2
));
465 return new OrderedParallelQuery
<TSource
> (new QueryOrderByNode
<TSource
> (source
.Node
, comparison
));
470 public static bool All
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, bool> predicate
)
473 throw new ArgumentNullException ("source");
474 if (predicate
== null)
475 throw new ArgumentNullException ("predicate");
477 CancellationTokenSource src
= new CancellationTokenSource ();
478 ParallelQuery
<TSource
> innerQuery
= source
.WithImplementerToken (src
);
482 innerQuery
.ForAll ((e
) => {
483 if (!predicate (e
)) {
488 } catch (OperationCanceledException e
) {
489 if (e
.CancellationToken
!= src
.Token
)
498 public static bool Any
<TSource
> (this ParallelQuery
<TSource
> source
)
500 return Any
<TSource
> (source
, (_
) => true);
503 public static bool Any
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, bool> predicate
)
506 throw new ArgumentNullException ("source");
507 if (predicate
== null)
508 throw new ArgumentNullException ("predicate");
510 return !source
.All ((e
) => !predicate (e
));
515 public static bool Contains
<TSource
> (this ParallelQuery
<TSource
> source
, TSource
value)
517 return Contains
<TSource
> (source
, value, EqualityComparer
<TSource
>.Default
);
520 public static bool Contains
<TSource
> (this ParallelQuery
<TSource
> source
, TSource
value, IEqualityComparer
<TSource
> comparer
)
523 throw new ArgumentNullException ("source");
524 if (comparer
== null)
525 comparer
= EqualityComparer
<TSource
>.Default
;
527 return Any
<TSource
> (source
, (e
) => comparer
.Equals (value));
531 #region SequenceEqual
532 public static bool SequenceEqual
<TSource
> (this ParallelQuery
<TSource
> first
,
533 ParallelQuery
<TSource
> second
)
536 throw new ArgumentNullException ("first");
538 throw new ArgumentNullException ("second");
540 return first
.SequenceEqual (second
, EqualityComparer
<TSource
>.Default
);
543 public static bool SequenceEqual
<TSource
> (this ParallelQuery
<TSource
> first
,
544 ParallelQuery
<TSource
> second
,
545 IEqualityComparer
<TSource
> comparer
)
548 throw new ArgumentNullException ("first");
550 throw new ArgumentNullException ("second");
551 if (comparer
== null)
552 comparer
= EqualityComparer
<TSource
>.Default
;
554 CancellationTokenSource source
= new CancellationTokenSource ();
555 ParallelQuery
<bool> innerQuery
556 = first
.Zip (second
, (e1
, e2
) => comparer
.Equals (e1
, e2
)).Where ((e
) => !e
).WithImplementerToken (source
);
561 innerQuery
.ForAll ((value) => {
565 } catch (OperationCanceledException e
) {
566 if (e
.CancellationToken
!= source
.Token
)
573 [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery<T> rather "
574 + "than System.Collections.Generic.IEnumerable<T>. To fix this problem, use the AsParallel() "
575 + "extension method to convert the right data source to System.Linq.ParallelQuery<T>.")]
576 public static bool SequenceEqual
<TSource
> (this ParallelQuery
<TSource
> first
, IEnumerable
<TSource
> second
)
578 throw new NotSupportedException ();
581 [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery<T> rather "
582 + "than System.Collections.Generic.IEnumerable<T>. To fix this problem, use the AsParallel() "
583 + "extension method to convert the right data source to System.Linq.ParallelQuery<T>.")]
584 public static bool SequenceEqual
<TSource
> (this ParallelQuery
<TSource
> first
,
585 IEnumerable
<TSource
> second
,
586 IEqualityComparer
<TSource
> comparer
)
588 throw new NotSupportedException ();
594 public static ParallelQuery
<IGrouping
<TKey
, TSource
>> GroupBy
<TSource
, TKey
> (this ParallelQuery
<TSource
> source
,
595 Func
<TSource
, TKey
> keySelector
)
597 return source
.GroupBy (keySelector
, EqualityComparer
<TKey
>.Default
);
600 public static ParallelQuery
<IGrouping
<TKey
, TSource
>> GroupBy
<TSource
, TKey
> (this ParallelQuery
<TSource
> source
,
601 Func
<TSource
, TKey
> keySelector
,
602 IEqualityComparer
<TKey
> comparer
)
604 return source
.GroupBy (keySelector
, (e
) => e
, comparer
);
607 public static ParallelQuery
<IGrouping
<TKey
, TElement
>> GroupBy
<TSource
, TKey
, TElement
> (this ParallelQuery
<TSource
> source
,
608 Func
<TSource
, TKey
> keySelector
,
609 Func
<TSource
, TElement
> elementSelector
)
611 return source
.GroupBy (keySelector
, elementSelector
, EqualityComparer
<TKey
>.Default
);
614 public static ParallelQuery
<TResult
> GroupBy
<TSource
, TKey
, TResult
> (this ParallelQuery
<TSource
> source
,
615 Func
<TSource
, TKey
> keySelector
,
616 Func
<TKey
, IEnumerable
<TSource
>, TResult
> resultSelector
)
618 return source
.GroupBy (keySelector
)
619 .Select ((g
) => resultSelector (g
.Key
, (IEnumerable
<TSource
>)g
));
622 public static ParallelQuery
<IGrouping
<TKey
, TElement
>> GroupBy
<TSource
, TKey
, TElement
> (this ParallelQuery
<TSource
> source
,
623 Func
<TSource
, TKey
> keySelector
,
624 Func
<TSource
, TElement
> elementSelector
,
625 IEqualityComparer
<TKey
> comparer
)
628 throw new ArgumentNullException ("source");
629 if (keySelector
== null)
630 throw new ArgumentNullException ("keySelector");
631 if (elementSelector
== null)
632 throw new ArgumentNullException ("elementSelector");
633 if (comparer
== null)
634 comparer
= EqualityComparer
<TKey
>.Default
;
636 return new ParallelQuery
<IGrouping
<TKey
, TElement
>> (new QueryGroupByNode
<TSource
, TKey
, TElement
> (source
.Node
, keySelector
, elementSelector
, comparer
));
639 public static ParallelQuery
<TResult
> GroupBy
<TSource
, TKey
, TElement
, TResult
> (this ParallelQuery
<TSource
> source
,
640 Func
<TSource
, TKey
> keySelector
,
641 Func
<TSource
, TElement
> elementSelector
,
642 Func
<TKey
, IEnumerable
<TElement
>, TResult
> resultSelector
)
644 return source
.GroupBy (keySelector
, elementSelector
)
645 .Select ((g
) => resultSelector (g
.Key
, (IEnumerable
<TElement
>)g
));
648 public static ParallelQuery
<TResult
> GroupBy
<TSource
, TKey
, TResult
> (this ParallelQuery
<TSource
> source
,
649 Func
<TSource
, TKey
> keySelector
,
650 Func
<TKey
, IEnumerable
<TSource
>, TResult
> resultSelector
,
651 IEqualityComparer
<TKey
> comparer
)
653 return source
.GroupBy (keySelector
, comparer
)
654 .Select ((g
) => resultSelector (g
.Key
, (IEnumerable
<TSource
>)g
));
657 public static ParallelQuery
<TResult
> GroupBy
<TSource
, TKey
, TElement
, TResult
> (this ParallelQuery
<TSource
> source
,
658 Func
<TSource
, TKey
> keySelector
,
659 Func
<TSource
, TElement
> elementSelector
,
660 Func
<TKey
, IEnumerable
<TElement
>, TResult
> resultSelector
,
661 IEqualityComparer
<TKey
> comparer
)
663 return source
.GroupBy (keySelector
, elementSelector
, comparer
)
664 .Select ((g
) => resultSelector (g
.Key
, (IEnumerable
<TElement
>)g
));
669 public static ParallelQuery
<TResult
> GroupJoin
<TOuter
, TInner
, TKey
, TResult
> (this ParallelQuery
<TOuter
> outer
,
670 ParallelQuery
<TInner
> inner
,
671 Func
<TOuter
, TKey
> outerKeySelector
,
672 Func
<TInner
, TKey
> innerKeySelector
,
673 Func
<TOuter
, IEnumerable
<TInner
>, TResult
> resultSelector
)
675 return outer
.GroupJoin (inner
, outerKeySelector
, innerKeySelector
, resultSelector
, EqualityComparer
<TKey
>.Default
);
678 public static ParallelQuery
<TResult
> GroupJoin
<TOuter
, TInner
, TKey
, TResult
> (this ParallelQuery
<TOuter
> outer
,
679 ParallelQuery
<TInner
> inner
,
680 Func
<TOuter
, TKey
> outerKeySelector
,
681 Func
<TInner
, TKey
> innerKeySelector
,
682 Func
<TOuter
, IEnumerable
<TInner
>, TResult
> resultSelector
,
683 IEqualityComparer
<TKey
> comparer
)
685 return outer
.Join (inner
.GroupBy (innerKeySelector
, (e
) => e
), outerKeySelector
, (e
) => e
.Key
, (e1
, e2
) => resultSelector (e1
, e2
), comparer
);
688 [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery<T> rather "
689 + "than System.Collections.Generic.IEnumerable<T>. To fix this problem, use the AsParallel() "
690 + "extension method to convert the right data source to System.Linq.ParallelQuery<T>.")]
691 public static ParallelQuery
<TResult
> GroupJoin
<TOuter
, TInner
, TKey
, TResult
> (this ParallelQuery
<TOuter
> outer
,
692 IEnumerable
<TInner
> inner
,
693 Func
<TOuter
, TKey
> outerKeySelector
,
694 Func
<TInner
, TKey
> innerKeySelector
,
695 Func
<TOuter
, IEnumerable
<TInner
>, TResult
> resultSelector
)
697 throw new NotSupportedException ();
700 [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery<T> rather "
701 + "than System.Collections.Generic.IEnumerable<T>. To fix this problem, use the AsParallel() "
702 + "extension method to convert the right data source to System.Linq.ParallelQuery<T>.")]
703 public static ParallelQuery
<TResult
> GroupJoin
<TOuter
, TInner
, TKey
, TResult
> (this ParallelQuery
<TOuter
> outer
,
704 IEnumerable
<TInner
> inner
,
705 Func
<TOuter
, TKey
> outerKeySelector
,
706 Func
<TInner
, TKey
> innerKeySelector
,
707 Func
<TOuter
, IEnumerable
<TInner
>, TResult
> resultSelector
,
708 IEqualityComparer
<TKey
> comparer
)
710 throw new NotSupportedException ();
715 public static TSource ElementAt
<TSource
> (this ParallelQuery
<TSource
> source
, int index
)
718 throw new ArgumentNullException ("source");
720 throw new ArgumentOutOfRangeException ("index");
723 return source
.First ();
724 } catch (InvalidOperationException
) {
725 throw new ArgumentOutOfRangeException ("index");
729 TSource result
= default (TSource
);
731 ParallelQuery
<TSource
> innerQuery
= source
.Where ((e
, i
) => i
== index
);
734 result
= innerQuery
.First ();
735 } catch (InvalidOperationException
) {
736 throw new ArgumentOutOfRangeException ("index");
742 public static TSource ElementAtOrDefault
<TSource
> (this ParallelQuery
<TSource
> source
, int index
)
745 throw new ArgumentNullException ("source");
748 return source
.ElementAt (index
);
749 } catch (ArgumentOutOfRangeException
) {
750 return default (TSource
);
756 public static ParallelQuery
<TSource
> Intersect
<TSource
> (this ParallelQuery
<TSource
> first
,
757 ParallelQuery
<TSource
> second
)
759 return Intersect
<TSource
> (first
, second
, EqualityComparer
<TSource
>.Default
);
762 public static ParallelQuery
<TSource
> Intersect
<TSource
> (this ParallelQuery
<TSource
> first
,
763 ParallelQuery
<TSource
> second
,
764 IEqualityComparer
<TSource
> comparer
)
767 throw new ArgumentNullException ("first");
769 throw new ArgumentNullException ("second");
770 if (comparer
== null)
771 comparer
= EqualityComparer
<TSource
>.Default
;
773 return new ParallelQuery
<TSource
> (new QuerySetNode
<TSource
> (SetInclusionDefaults
.Intersect
, comparer
, first
.Node
, second
.Node
));
776 [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery<T> rather "
777 + "than System.Collections.Generic.IEnumerable<T>. To fix this problem, use the AsParallel() "
778 + "extension method to convert the right data source to System.Linq.ParallelQuery<T>.")]
779 public static ParallelQuery
<TSource
> Intersect
<TSource
> (this ParallelQuery
<TSource
> first
, IEnumerable
<TSource
> second
)
781 throw new NotSupportedException ();
784 [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery<T> rather "
785 + "than System.Collections.Generic.IEnumerable<T>. To fix this problem, use the AsParallel() "
786 + "extension method to convert the right data source to System.Linq.ParallelQuery<T>.")]
787 public static ParallelQuery
<TSource
> Intersect
<TSource
> (this ParallelQuery
<TSource
> first
,
788 IEnumerable
<TSource
> second
,
789 IEqualityComparer
<TSource
> comparer
)
791 throw new NotSupportedException ();
796 public static ParallelQuery
<TResult
> Join
<TOuter
, TInner
, TKey
, TResult
> (this ParallelQuery
<TOuter
> outer
,
797 ParallelQuery
<TInner
> inner
,
798 Func
<TOuter
, TKey
> outerKeySelector
,
799 Func
<TInner
, TKey
> innerKeySelector
,
800 Func
<TOuter
, TInner
, TResult
> resultSelector
)
802 return outer
.Join (inner
, outerKeySelector
, innerKeySelector
, resultSelector
, EqualityComparer
<TKey
>.Default
);
805 public static ParallelQuery
<TResult
> Join
<TOuter
, TInner
, TKey
, TResult
> (this ParallelQuery
<TOuter
> outer
,
806 ParallelQuery
<TInner
> inner
,
807 Func
<TOuter
, TKey
> outerKeySelector
,
808 Func
<TInner
, TKey
> innerKeySelector
,
809 Func
<TOuter
, TInner
, TResult
> resultSelector
,
810 IEqualityComparer
<TKey
> comparer
)
812 return new ParallelQuery
<TResult
> (new QueryJoinNode
<TOuter
, TInner
, TKey
, TResult
> (outer
.Node
, inner
.Node
, outerKeySelector
, innerKeySelector
, resultSelector
, comparer
));
815 [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery<T> rather "
816 + "than System.Collections.Generic.IEnumerable<T>. To fix this problem, use the AsParallel() "
817 + "extension method to convert the right data source to System.Linq.ParallelQuery<T>.")]
818 public static ParallelQuery
<TResult
> Join
<TOuter
, TInner
, TKey
, TResult
> (this ParallelQuery
<TOuter
> outer
,
819 IEnumerable
<TInner
> inner
,
820 Func
<TOuter
, TKey
> outerKeySelector
,
821 Func
<TInner
, TKey
> innerKeySelector
,
822 Func
<TOuter
, TInner
, TResult
> resultSelector
)
824 throw new NotSupportedException ();
827 [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery<T> rather "
828 + "than System.Collections.Generic.IEnumerable<T>. To fix this problem, use the AsParallel() "
829 + "extension method to convert the right data source to System.Linq.ParallelQuery<T>.")]
830 public static ParallelQuery
<TResult
> Join
<TOuter
, TInner
, TKey
, TResult
> (this ParallelQuery
<TOuter
> outer
,
831 IEnumerable
<TInner
> inner
,
832 Func
<TOuter
, TKey
> outerKeySelector
,
833 Func
<TInner
, TKey
> innerKeySelector
,
834 Func
<TOuter
, TInner
, TResult
> resultSelector
,
835 IEqualityComparer
<TKey
> comparer
)
837 throw new NotSupportedException ();
842 public static ParallelQuery
<TSource
> Except
<TSource
> (this ParallelQuery
<TSource
> first
,
843 ParallelQuery
<TSource
> second
)
845 return Except
<TSource
> (first
, second
, EqualityComparer
<TSource
>.Default
);
848 public static ParallelQuery
<TSource
> Except
<TSource
> (this ParallelQuery
<TSource
> first
,
849 ParallelQuery
<TSource
> second
,
850 IEqualityComparer
<TSource
> comparer
)
853 throw new ArgumentNullException ("first");
855 throw new ArgumentNullException ("second");
856 if (comparer
== null)
857 comparer
= EqualityComparer
<TSource
>.Default
;
859 return new ParallelQuery
<TSource
> (new QuerySetNode
<TSource
> (SetInclusionDefaults
.Except
,
860 comparer
, first
.Node
, second
.Node
));
863 [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery<T> rather "
864 + "than System.Collections.Generic.IEnumerable<T>. To fix this problem, use the AsParallel() "
865 + "extension method to convert the right data source to System.Linq.ParallelQuery<T>.")]
866 public static ParallelQuery
<TSource
> Except
<TSource
> (this ParallelQuery
<TSource
> first
,
867 IEnumerable
<TSource
> second
)
869 throw new NotSupportedException ();
872 [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery<T> rather "
873 + "than System.Collections.Generic.IEnumerable<T>. To fix this problem, use the AsParallel() "
874 + "extension method to convert the right data source to System.Linq.ParallelQuery<T>.")]
875 public static ParallelQuery
<TSource
> Except
<TSource
> (this ParallelQuery
<TSource
> first
,
876 IEnumerable
<TSource
> second
,
877 IEqualityComparer
<TSource
> comparer
)
879 throw new NotSupportedException ();
884 public static ParallelQuery
<TSource
> Distinct
<TSource
> (this ParallelQuery
<TSource
> source
)
886 return Distinct
<TSource
> (source
, EqualityComparer
<TSource
>.Default
);
889 public static ParallelQuery
<TSource
> Distinct
<TSource
> (this ParallelQuery
<TSource
> source
, IEqualityComparer
<TSource
> comparer
)
892 throw new ArgumentNullException ("source");
893 if (comparer
== null)
894 comparer
= EqualityComparer
<TSource
>.Default
;
896 return new ParallelQuery
<TSource
> (new QuerySetNode
<TSource
> (SetInclusionDefaults
.Distinct
, comparer
,
902 [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery<T> rather "
903 + "than System.Collections.Generic.IEnumerable<T>. To fix this problem, use the AsParallel() "
904 + "extension method to convert the right data source to System.Linq.ParallelQuery<T>.")]
905 public static ParallelQuery
<TSource
> Union
<TSource
> (this ParallelQuery
<TSource
> first
,
906 IEnumerable
<TSource
> second
)
908 throw new NotSupportedException ();
911 [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery<T> rather "
912 + "than System.Collections.Generic.IEnumerable<T>. To fix this problem, use the AsParallel() "
913 + "extension method to convert the right data source to System.Linq.ParallelQuery<T>.")]
914 public static ParallelQuery
<TSource
> Union
<TSource
>(this ParallelQuery
<TSource
> first
,
915 IEnumerable
<TSource
> second
,
916 IEqualityComparer
<TSource
> comparer
)
918 throw new NotSupportedException ();
921 public static ParallelQuery
<TSource
> Union
<TSource
> (this ParallelQuery
<TSource
> first
,
922 ParallelQuery
<TSource
> second
)
924 return first
.Union (second
, EqualityComparer
<TSource
>.Default
);
927 public static ParallelQuery
<TSource
> Union
<TSource
> (this ParallelQuery
<TSource
> first
,
928 ParallelQuery
<TSource
> second
,
929 IEqualityComparer
<TSource
> comparer
)
932 throw new ArgumentNullException ("first");
934 throw new ArgumentNullException ("second");
935 if (comparer
== null)
936 comparer
= EqualityComparer
<TSource
>.Default
;
938 return new ParallelQuery
<TSource
> (new QuerySetNode
<TSource
> (SetInclusionDefaults
.Union
, comparer
, first
.Node
, second
.Node
));
943 public static ParallelQuery
<TSource
> Take
<TSource
> (this ParallelQuery
<TSource
> source
, int count
)
946 throw new ArgumentNullException ("source");
948 return new ParallelQuery
<TSource
> (new QueryHeadWorkerNode
<TSource
> (source
.Node
, count
));
951 public static ParallelQuery
<TSource
> TakeWhile
<TSource
> (this ParallelQuery
<TSource
> source
,
952 Func
<TSource
, bool> predicate
)
955 throw new ArgumentNullException ("source");
956 if (predicate
== null)
957 throw new ArgumentNullException ("predicate");
959 return new ParallelQuery
<TSource
> (new QueryHeadWorkerNode
<TSource
> (source
.Node
, (e
, _
) => predicate (e
), false));
962 public static ParallelQuery
<TSource
> TakeWhile
<TSource
> (this ParallelQuery
<TSource
> source
,
963 Func
<TSource
, int, bool> predicate
)
966 throw new ArgumentNullException ("source");
967 if (predicate
== null)
968 throw new ArgumentNullException ("predicate");
970 return new ParallelQuery
<TSource
> (new QueryHeadWorkerNode
<TSource
> (source
.Node
, predicate
, true));
975 public static ParallelQuery
<TSource
> Skip
<TSource
> (this ParallelQuery
<TSource
> source
, int count
)
978 throw new ArgumentNullException ("source");
980 return source
.Node
.IsOrdered () ?
981 source
.Where ((e
, i
) => i
>= count
) :
982 source
.Where ((e
) => count
< 0 || Interlocked
.Decrement (ref count
) < 0);
986 public static ParallelQuery
<TSource
> SkipWhile
<TSource
> (this ParallelQuery
<TSource
> source
,
987 Func
<TSource
, bool> predicate
)
990 throw new ArgumentNullException ("source");
991 if (predicate
== null)
992 throw new ArgumentNullException ("predicate");
994 return source
.Node
.IsOrdered () ?
995 source
.SkipWhile ((e
, i
) => predicate (e
)) :
996 source
.Where ((e
) => !predicate (e
));
999 public static ParallelQuery
<TSource
> SkipWhile
<TSource
> (this ParallelQuery
<TSource
> source
,
1000 Func
<TSource
, int, bool> predicate
)
1003 throw new ArgumentNullException ("source");
1004 if (predicate
== null)
1005 throw new ArgumentNullException ("predicate");
1007 int indexCache
= int.MaxValue
;
1009 return source
.Where ((e
, i
) => i
>= indexCache
|| (!predicate (e
, i
) && (indexCache
= i
) == i
));
1014 static TSource SingleInternal
<TSource
> (this ParallelQuery
<TSource
> source
, params TSource
[] init
)
1016 TSource result
= default(TSource
);
1017 bool hasValue
= false;
1019 foreach (TSource element
in source
) {
1021 throw new InvalidOperationException ("The input sequence contains more than one element.");
1027 if (!hasValue
&& init
.Length
!= 0) {
1033 throw new InvalidOperationException ("The input sequence is empty.");
1038 public static TSource Single
<TSource
> (this ParallelQuery
<TSource
> source
)
1041 throw new ArgumentNullException ("source");
1043 return SingleInternal
<TSource
> (source
);
1046 public static TSource Single
<TSource
> (this ParallelQuery
<TSource
> source
,
1047 Func
<TSource
, bool> predicate
)
1050 throw new ArgumentNullException ("source");
1051 if (predicate
== null)
1052 throw new ArgumentNullException ("predicate");
1054 return source
.Where (predicate
).Single ();
1057 public static TSource SingleOrDefault
<TSource
> (this ParallelQuery
<TSource
> source
)
1060 throw new ArgumentNullException ("source");
1062 return SingleInternal
<TSource
> (source
, default (TSource
));
1065 public static TSource SingleOrDefault
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, bool> predicate
)
1068 throw new ArgumentNullException ("source");
1069 if (predicate
== null)
1070 throw new ArgumentNullException ("predicate");
1072 return source
.Where (predicate
).SingleOrDefault ();
1077 public static int Count
<TSource
> (this ParallelQuery
<TSource
> source
)
1080 throw new ArgumentNullException ("source");
1082 return source
.Aggregate
<TSource
, int, int> (() => 0,
1083 (acc
, e
) => acc
+ 1,
1084 (acc1
, acc2
) => acc1
+ acc2
,
1085 (result
) => result
);
1088 public static int Count
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, bool> predicate
)
1091 throw new ArgumentNullException ("source");
1092 if (predicate
== null)
1093 throw new ArgumentNullException ("predicate");
1095 return source
.Where (predicate
).Count ();
1098 public static long LongCount
<TSource
> (this ParallelQuery
<TSource
> source
)
1101 throw new ArgumentNullException ("source");
1103 return source
.Aggregate
<TSource
, long, long> (() => 0,
1104 (acc
, e
) => acc
+ 1,
1105 (acc1
, acc2
) => acc1
+ acc2
,
1106 (result
) => result
);
1109 public static long LongCount
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, bool> predicate
)
1112 throw new ArgumentNullException ("source");
1113 if (predicate
== null)
1114 throw new ArgumentNullException ("predicate");
1116 return source
.Where (predicate
).LongCount ();
1121 public static double Average (this ParallelQuery
<int> source
)
1124 throw new ArgumentNullException ("source");
1126 return source
.Aggregate (() => new int[2],
1127 (acc
, e
) => { acc[0] += e; acc[1]++; return acc; }
,
1128 (acc1
, acc2
) => { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; }
,
1129 (acc
) => acc
[0] / ((double)acc
[1]));
1132 public static double Average (this ParallelQuery
<long> source
)
1135 throw new ArgumentNullException ("source");
1137 return source
.Aggregate (() => new long[2],
1138 (acc
, e
) => { acc[0] += e; acc[1]++; return acc; }
,
1139 (acc1
, acc2
) => { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; }
,
1140 (acc
) => acc
[0] / ((double)acc
[1]));
1143 public static decimal Average (this ParallelQuery
<decimal> source
)
1146 throw new ArgumentNullException ("source");
1148 return source
.Aggregate (() => new decimal[2],
1149 (acc
, e
) => { acc[0] += e; acc[1]++; return acc; }
,
1150 (acc1
, acc2
) => { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; }
,
1151 (acc
) => acc
[0] / acc
[1]);
1154 public static double Average (this ParallelQuery
<double> source
)
1157 throw new ArgumentNullException ("source");
1159 return source
.Aggregate (() => new double[2],
1160 (acc
, e
) => { acc[0] += e; acc[1]++; return acc; }
,
1161 (acc1
, acc2
) => { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; }
,
1162 (acc
) => acc
[0] / ((double)acc
[1]));
1165 public static float Average (this ParallelQuery
<float> source
)
1168 throw new ArgumentNullException ("source");
1170 return source
.Aggregate (() => new float[2],
1171 (acc
, e
) => { acc[0] += e; acc[1]++; return acc; }
,
1172 (acc1
, acc2
) => { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; }
,
1173 (acc
) => acc
[0] / acc
[1]);
1177 #region More Average
1178 public static double? Average (this ParallelQuery
<int?> source
)
1181 throw new ArgumentNullException ("source");
1183 return source
.Select ((e
) => e
.HasValue
? e
.Value
: 0).Average ();;
1186 public static double? Average (this ParallelQuery
<long?> source
)
1189 throw new ArgumentNullException ("source");
1191 return source
.Select ((e
) => e
.HasValue
? e
.Value
: 0).Average ();
1194 public static decimal? Average (this ParallelQuery
<decimal?> source
)
1197 throw new ArgumentNullException ("source");
1199 return source
.Select ((e
) => e
.HasValue
? e
.Value
: 0).Average ();
1202 public static double? Average (this ParallelQuery
<double?> source
)
1205 throw new ArgumentNullException ("source");
1207 return source
.Select ((e
) => e
.HasValue
? e
.Value
: 0).Average ();
1210 public static float? Average (this ParallelQuery
<float?> source
)
1213 throw new ArgumentNullException ("source");
1215 return source
.Select ((e
) => e
.HasValue
? e
.Value
: 0).Average ();
1218 public static double Average
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, int> selector
)
1221 throw new ArgumentNullException ("source");
1222 if (selector
== null)
1223 throw new ArgumentNullException ("selector");
1225 return source
.Select (selector
).Average ();
1228 public static double Average
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, long> selector
)
1231 throw new ArgumentNullException ("source");
1232 if (selector
== null)
1233 throw new ArgumentNullException ("selector");
1235 return source
.Select (selector
).Average ();
1238 public static float Average
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, float> selector
)
1241 throw new ArgumentNullException ("source");
1242 if (selector
== null)
1243 throw new ArgumentNullException ("selector");
1245 return source
.Select (selector
).Average ();
1248 public static double Average
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, double> selector
)
1251 throw new ArgumentNullException ("source");
1252 if (selector
== null)
1253 throw new ArgumentNullException ("selector");
1255 return source
.Select (selector
).Average ();
1258 public static decimal Average
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, decimal> selector
)
1261 throw new ArgumentNullException ("source");
1262 if (selector
== null)
1263 throw new ArgumentNullException ("selector");
1265 return source
.Select (selector
).Average ();
1268 public static double? Average
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, int?> selector
)
1271 throw new ArgumentNullException ("source");
1272 if (selector
== null)
1273 throw new ArgumentNullException ("selector");
1275 return source
.Select (selector
).Average ();
1278 public static double? Average
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, long?> selector
)
1281 throw new ArgumentNullException ("source");
1282 if (selector
== null)
1283 throw new ArgumentNullException ("selector");
1285 return source
.Select (selector
).Average ();
1288 public static float? Average
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, float?> selector
)
1291 throw new ArgumentNullException ("source");
1292 if (selector
== null)
1293 throw new ArgumentNullException ("selector");
1295 return source
.Select (selector
).Average ();
1298 public static double? Average
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, double?> selector
)
1301 throw new ArgumentNullException ("source");
1302 if (selector
== null)
1303 throw new ArgumentNullException ("selector");
1305 return source
.Select (selector
).Average ();
1308 public static decimal? Average
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, decimal?> selector
)
1311 throw new ArgumentNullException ("source");
1312 if (selector
== null)
1313 throw new ArgumentNullException ("selector");
1315 return source
.Select (selector
).Average ();
1320 public static int Sum (this ParallelQuery
<int> source
)
1323 throw new ArgumentNullException ("source");
1325 return source
.Aggregate (0, (e1
, e2
) => e1
+ e2
, (sum1
, sum2
) => sum1
+ sum2
, (sum
) => sum
);
1328 public static long Sum (this ParallelQuery
<long> source
)
1331 throw new ArgumentNullException ("source");
1333 return source
.Aggregate ((long)0, (e1
, e2
) => e1
+ e2
, (sum1
, sum2
) => sum1
+ sum2
, (sum
) => sum
);
1336 public static float Sum (this ParallelQuery
<float> source
)
1339 throw new ArgumentNullException ("source");
1341 return source
.Aggregate (0.0f
, (e1
, e2
) => e1
+ e2
, (sum1
, sum2
) => sum1
+ sum2
, (sum
) => sum
);
1344 public static double Sum (this ParallelQuery
<double> source
)
1347 throw new ArgumentNullException ("source");
1349 return source
.Aggregate (0.0, (e1
, e2
) => e1
+ e2
, (sum1
, sum2
) => sum1
+ sum2
, (sum
) => sum
);
1352 public static decimal Sum (this ParallelQuery
<decimal> source
)
1355 throw new ArgumentNullException ("source");
1357 return source
.Aggregate ((decimal)0, (e1
, e2
) => e1
+ e2
, (sum1
, sum2
) => sum1
+ sum2
, (sum
) => sum
);
1360 public static int? Sum (this ParallelQuery
<int?> source
)
1362 return source
.Select ((e
) => e
.HasValue
? e
.Value
: 0).Sum ();
1365 public static long? Sum (this ParallelQuery
<long?> source
)
1368 throw new ArgumentNullException ("source");
1370 return source
.Select ((e
) => e
.HasValue
? e
.Value
: 0).Sum ();
1373 public static float? Sum (this ParallelQuery
<float?> source
)
1376 throw new ArgumentNullException ("source");
1378 return source
.Select ((e
) => e
.HasValue
? e
.Value
: 0).Sum ();
1381 public static double? Sum (this ParallelQuery
<double?> source
)
1384 throw new ArgumentNullException ("source");
1386 return source
.Select ((e
) => e
.HasValue
? e
.Value
: 0).Sum ();
1389 public static decimal? Sum (this ParallelQuery
<decimal?> source
)
1392 throw new ArgumentNullException ("source");
1394 return source
.Select ((e
) => e
.HasValue
? e
.Value
: 0).Sum ();
1397 public static int Sum
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, int> selector
)
1400 throw new ArgumentNullException ("source");
1401 if (selector
== null)
1402 throw new ArgumentNullException ("selector");
1404 return source
.Select (selector
).Sum ();
1407 public static long Sum
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, long> selector
)
1410 throw new ArgumentNullException ("source");
1411 if (selector
== null)
1412 throw new ArgumentNullException ("selector");
1414 return source
.Select (selector
).Sum ();
1417 public static decimal Sum
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, decimal> selector
)
1420 throw new ArgumentNullException ("source");
1421 if (selector
== null)
1422 throw new ArgumentNullException ("selector");
1424 return source
.Select (selector
).Sum ();
1427 public static float Sum
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, float> selector
)
1430 throw new ArgumentNullException ("source");
1431 if (selector
== null)
1432 throw new ArgumentNullException ("selector");
1434 return source
.Select (selector
).Sum ();
1437 public static double Sum
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, double> selector
)
1440 throw new ArgumentNullException ("source");
1441 if (selector
== null)
1442 throw new ArgumentNullException ("selector");
1444 return source
.Select (selector
).Sum ();
1447 public static int? Sum
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, int?> selector
)
1450 throw new ArgumentNullException ("source");
1451 if (selector
== null)
1452 throw new ArgumentNullException ("selector");
1454 return source
.Select (selector
).Sum ();
1457 public static long? Sum
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, long?> selector
)
1460 throw new ArgumentNullException ("source");
1461 if (selector
== null)
1462 throw new ArgumentNullException ("selector");
1464 return source
.Select (selector
).Sum ();
1467 public static decimal? Sum
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, decimal?> selector
)
1470 throw new ArgumentNullException ("source");
1471 if (selector
== null)
1472 throw new ArgumentNullException ("selector");
1474 return source
.Select (selector
).Sum ();
1477 public static float? Sum
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, float?> selector
)
1480 throw new ArgumentNullException ("source");
1481 if (selector
== null)
1482 throw new ArgumentNullException ("selector");
1484 return source
.Select (selector
).Sum ();
1487 public static double? Sum
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, double?> selector
)
1490 throw new ArgumentNullException ("source");
1491 if (selector
== null)
1492 throw new ArgumentNullException ("selector");
1494 return source
.Select (selector
).Sum ();
1499 static T BestOrder
<T
> (ParallelQuery
<T
> source
, Func
<T
, T
, bool> bestSelector
, T seed
)
1502 throw new ArgumentNullException ("source");
1506 best
= source
.Aggregate (() => seed
,
1507 (first
, second
) => (bestSelector(first
, second
)) ? first
: second
,
1508 (first
, second
) => (bestSelector(first
, second
)) ? first
: second
,
1513 public static int Min (this ParallelQuery
<int> source
)
1515 return BestOrder (source
, (first
, second
) => first
< second
, int.MaxValue
);
1518 public static long Min (this ParallelQuery
<long> source
)
1520 return BestOrder (source
, (first
, second
) => first
< second
, long.MaxValue
);
1523 public static float Min (this ParallelQuery
<float> source
)
1525 return BestOrder (source
, (first
, second
) => first
< second
, float.MaxValue
);
1528 public static double Min (this ParallelQuery
<double> source
)
1530 return BestOrder (source
, (first
, second
) => first
< second
, double.MaxValue
);
1533 public static decimal Min (this ParallelQuery
<decimal> source
)
1535 return BestOrder (source
, (first
, second
) => first
< second
, decimal.MaxValue
);
1538 public static TSource Min
<TSource
> (this ParallelQuery
<TSource
> source
)
1540 IComparer
<TSource
> comparer
= Comparer
<TSource
>.Default
;
1542 return BestOrder (source
, (first
, second
) => comparer
.Compare (first
, second
) < 0, default (TSource
));
1545 public static TResult Min
<TSource
, TResult
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, TResult
> selector
)
1548 throw new ArgumentNullException ("source");
1549 if (selector
== null)
1550 throw new ArgumentNullException ("selector");
1552 return source
.Select (selector
).Min ();
1555 public static int? Min (this ParallelQuery
<int?> source
)
1558 throw new ArgumentNullException ("source");
1560 return source
.Select ((e
) => e
.HasValue
? e
.Value
: int.MaxValue
).Min ();
1563 public static long? Min (this ParallelQuery
<long?> source
)
1566 throw new ArgumentNullException ("source");
1568 return source
.Select ((e
) => e
.HasValue
? e
.Value
: long.MaxValue
).Min ();
1571 public static float? Min (this ParallelQuery
<float?> source
)
1574 throw new ArgumentNullException ("source");
1576 return source
.Select ((e
) => e
.HasValue
? e
.Value
: float.MaxValue
).Min ();
1579 public static double? Min (this ParallelQuery
<double?> source
)
1582 throw new ArgumentNullException ("source");
1584 return source
.Select ((e
) => e
.HasValue
? e
.Value
: double.MaxValue
).Min ();
1587 public static decimal? Min (this ParallelQuery
<decimal?> source
)
1590 throw new ArgumentNullException ("source");
1592 return source
.Select ((e
) => e
.HasValue
? e
.Value
: decimal.MaxValue
).Min ();
1595 public static int Min
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, int> selector
)
1598 throw new ArgumentNullException ("source");
1599 if (selector
== null)
1600 throw new ArgumentNullException ("selector");
1602 return source
.Select (selector
).Min ();
1605 public static long Min
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, long> selector
)
1608 throw new ArgumentNullException ("source");
1609 if (selector
== null)
1610 throw new ArgumentNullException ("selector");
1612 return source
.Select (selector
).Min ();
1615 public static float Min
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, float> selector
)
1618 throw new ArgumentNullException ("source");
1619 if (selector
== null)
1620 throw new ArgumentNullException ("selector");
1622 return source
.Select (selector
).Min ();
1625 public static double Min
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, double> selector
)
1628 throw new ArgumentNullException ("source");
1629 if (selector
== null)
1630 throw new ArgumentNullException ("selector");
1632 return source
.Select (selector
).Min ();
1635 public static decimal Min
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, decimal> selector
)
1638 throw new ArgumentNullException ("source");
1639 if (selector
== null)
1640 throw new ArgumentNullException ("selector");
1642 return source
.Select (selector
).Min ();
1645 public static int? Min
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, int?> selector
)
1648 throw new ArgumentNullException ("source");
1649 if (selector
== null)
1650 throw new ArgumentNullException ("selector");
1652 return source
.Select (selector
).Min ();
1655 public static long? Min
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, long?> selector
)
1658 throw new ArgumentNullException ("source");
1659 if (selector
== null)
1660 throw new ArgumentNullException ("selector");
1662 return source
.Select (selector
).Min ();
1665 public static float? Min
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, float?> selector
)
1668 throw new ArgumentNullException ("source");
1669 if (selector
== null)
1670 throw new ArgumentNullException ("selector");
1672 return source
.Select (selector
).Min ();
1675 public static double? Min
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, double?> selector
)
1678 throw new ArgumentNullException ("source");
1679 if (selector
== null)
1680 throw new ArgumentNullException ("selector");
1682 return source
.Select (selector
).Min ();
1685 public static decimal? Min
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, decimal?> selector
)
1688 throw new ArgumentNullException ("source");
1689 if (selector
== null)
1690 throw new ArgumentNullException ("selector");
1692 return source
.Select (selector
).Min ();
1695 public static int Max (this ParallelQuery
<int> source
)
1697 return BestOrder (source
, (first
, second
) => first
> second
, int.MinValue
);
1700 public static long Max(this ParallelQuery
<long> source
)
1702 return BestOrder(source
, (first
, second
) => first
> second
, long.MinValue
);
1705 public static float Max (this ParallelQuery
<float> source
)
1707 return BestOrder(source
, (first
, second
) => first
> second
, float.MinValue
);
1710 public static double Max (this ParallelQuery
<double> source
)
1712 return BestOrder(source
, (first
, second
) => first
> second
, double.MinValue
);
1715 public static decimal Max (this ParallelQuery
<decimal> source
)
1717 return BestOrder(source
, (first
, second
) => first
> second
, decimal.MinValue
);
1720 public static TSource Max
<TSource
> (this ParallelQuery
<TSource
> source
)
1722 IComparer
<TSource
> comparer
= Comparer
<TSource
>.Default
;
1724 return BestOrder (source
, (first
, second
) => comparer
.Compare (first
, second
) > 0, default (TSource
));
1727 public static TResult Max
<TSource
, TResult
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, TResult
> selector
)
1730 throw new ArgumentNullException ("source");
1731 if (selector
== null)
1732 throw new ArgumentNullException ("selector");
1734 return source
.Select (selector
).Max ();
1737 public static int? Max (this ParallelQuery
<int?> source
)
1740 throw new ArgumentNullException ("source");
1742 return source
.Select ((e
) => e
.HasValue
? e
.Value
: int.MinValue
).Max ();
1745 public static long? Max (this ParallelQuery
<long?> source
)
1748 throw new ArgumentNullException ("source");
1750 return source
.Select ((e
) => e
.HasValue
? e
.Value
: long.MinValue
).Max ();
1753 public static float? Max (this ParallelQuery
<float?> source
)
1756 throw new ArgumentNullException ("source");
1758 return source
.Select ((e
) => e
.HasValue
? e
.Value
: float.MinValue
).Max ();
1761 public static double? Max (this ParallelQuery
<double?> source
)
1764 throw new ArgumentNullException ("source");
1766 return source
.Select ((e
) => e
.HasValue
? e
.Value
: double.MinValue
).Max ();
1769 public static decimal? Max (this ParallelQuery
<decimal?> source
)
1772 throw new ArgumentNullException ("source");
1774 return source
.Select ((e
) => e
.HasValue
? e
.Value
: decimal.MinValue
).Max ();
1777 public static int Max
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, int> selector
)
1780 throw new ArgumentNullException ("source");
1781 if (selector
== null)
1782 throw new ArgumentNullException ("selector");
1784 return source
.Select (selector
).Max ();
1787 public static long Max
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, long> selector
)
1790 throw new ArgumentNullException ("source");
1791 if (selector
== null)
1792 throw new ArgumentNullException ("selector");
1794 return source
.Select (selector
).Max ();
1797 public static float Max
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, float> selector
)
1800 throw new ArgumentNullException ("source");
1801 if (selector
== null)
1802 throw new ArgumentNullException ("selector");
1804 return source
.Select (selector
).Max ();
1807 public static double Max
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, double> selector
)
1810 throw new ArgumentNullException ("source");
1811 if (selector
== null)
1812 throw new ArgumentNullException ("selector");
1814 return source
.Select (selector
).Max ();
1817 public static decimal Max
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, decimal> selector
)
1820 throw new ArgumentNullException ("source");
1821 if (selector
== null)
1822 throw new ArgumentNullException ("selector");
1824 return source
.Select (selector
).Max ();
1827 public static int? Max
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, int?> selector
)
1830 throw new ArgumentNullException ("source");
1831 if (selector
== null)
1832 throw new ArgumentNullException ("selector");
1834 return source
.Select (selector
).Max ();
1837 public static long? Max
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, long?> selector
)
1840 throw new ArgumentNullException ("source");
1841 if (selector
== null)
1842 throw new ArgumentNullException ("selector");
1844 return source
.Select (selector
).Max ();
1847 public static float? Max
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, float?> selector
)
1850 throw new ArgumentNullException ("source");
1851 if (selector
== null)
1852 throw new ArgumentNullException ("selector");
1854 return source
.Select (selector
).Max ();
1857 public static double? Max
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, double?> selector
)
1860 throw new ArgumentNullException ("source");
1861 if (selector
== null)
1862 throw new ArgumentNullException ("selector");
1864 return source
.Select (selector
).Max ();
1867 public static decimal? Max
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, decimal?> selector
)
1870 throw new ArgumentNullException ("source");
1871 if (selector
== null)
1872 throw new ArgumentNullException ("selector");
1874 return source
.Select (selector
).Max ();
1878 #region Cast / OfType
1879 public static ParallelQuery
<TResult
> Cast
<TResult
> (this ParallelQuery source
)
1882 throw new ArgumentNullException ("source");
1884 return source
.TypedQuery
.Select ((e
) => (TResult
)e
);
1887 public static ParallelQuery
<TResult
> OfType
<TResult
> (this ParallelQuery source
)
1890 throw new ArgumentNullException ("source");
1892 return source
.TypedQuery
.Where ((e
) => e
is TResult
).Cast
<TResult
> ();
1897 public static ParallelQuery
<TSource
> Reverse
<TSource
> (this ParallelQuery
<TSource
> source
)
1900 throw new ArgumentNullException ("source");
1902 return new ParallelQuery
<TSource
> (new QueryReverseNode
<TSource
> (source
));
1906 #region ToArray - ToList - ToDictionary - ToLookup
1907 public static List
<TSource
> ToList
<TSource
> (this ParallelQuery
<TSource
> source
)
1910 throw new ArgumentNullException ("source");
1912 if (source
.Node
.IsOrdered ())
1913 return ToListOrdered (source
);
1915 List
<TSource
> temp
= source
.Aggregate (() => new List
<TSource
>(50),
1916 (list
, e
) => { list.Add (e); return list; }
,
1917 (list
, list2
) => { list.AddRange (list2); return list; }
,
1922 internal static List
<TSource
> ToListOrdered
<TSource
> (this ParallelQuery
<TSource
> source
)
1924 List
<TSource
> result
= new List
<TSource
> ();
1926 foreach (TSource element
in source
)
1927 result
.Add (element
);
1932 public static TSource
[] ToArray
<TSource
> (this ParallelQuery
<TSource
> source
)
1935 throw new ArgumentNullException ("source");
1937 if (source
.Node
.IsOrdered ())
1938 return ToListOrdered (source
).ToArray ();
1940 TSource
[] result
= null;
1942 Func
<List
<TSource
>, TSource
, List
<TSource
>> intermediate
= (list
, e
) => {
1943 list
.Add (e
); return list
;
1946 Action
<IList
<List
<TSource
>>> final
= (list
) => {
1949 for (int i
= 0; i
< list
.Count
; i
++)
1950 count
+= list
[i
].Count
;
1952 result
= new TSource
[count
];
1953 int insertIndex
= -1;
1955 for (int i
= 0; i
< list
.Count
; i
++)
1956 for (int j
= 0; j
< list
[i
].Count
; j
++)
1957 result
[++insertIndex
] = list
[i
][j
];
1960 ParallelExecuter
.ProcessAndAggregate
<TSource
, List
<TSource
>> (source
.Node
,
1961 () => new List
<TSource
> (),
1968 public static Dictionary
<TKey
, TSource
> ToDictionary
<TSource
, TKey
> (this ParallelQuery
<TSource
> source
,
1969 Func
<TSource
, TKey
> keySelector
,
1970 IEqualityComparer
<TKey
> comparer
)
1972 return ToDictionary
<TSource
, TKey
, TSource
> (source
, keySelector
, (e
) => e
, comparer
);
1975 public static Dictionary
<TKey
, TSource
> ToDictionary
<TSource
, TKey
> (this ParallelQuery
<TSource
> source
,
1976 Func
<TSource
, TKey
> keySelector
)
1978 return ToDictionary
<TSource
, TKey
, TSource
> (source
, keySelector
, (e
) => e
, EqualityComparer
<TKey
>.Default
);
1981 public static Dictionary
<TKey
, TElement
> ToDictionary
<TSource
, TKey
, TElement
> (this ParallelQuery
<TSource
> source
,
1982 Func
<TSource
, TKey
> keySelector
,
1983 Func
<TSource
, TElement
> elementSelector
)
1985 return ToDictionary
<TSource
, TKey
, TElement
> (source
, keySelector
, elementSelector
, EqualityComparer
<TKey
>.Default
);
1988 public static Dictionary
<TKey
, TElement
> ToDictionary
<TSource
, TKey
, TElement
> (this ParallelQuery
<TSource
> source
,
1989 Func
<TSource
, TKey
> keySelector
,
1990 Func
<TSource
, TElement
> elementSelector
,
1991 IEqualityComparer
<TKey
> comparer
)
1994 throw new ArgumentNullException ("source");
1995 if (keySelector
== null)
1996 throw new ArgumentNullException ("keySelector");
1997 if (comparer
== null)
1998 comparer
= EqualityComparer
<TKey
>.Default
;
1999 if (elementSelector
== null)
2000 throw new ArgumentNullException ("elementSelector");
2002 return source
.Aggregate (() => new Dictionary
<TKey
, TElement
> (comparer
),
2003 (d
, e
) => { d.Add (keySelector (e), elementSelector (e)); return d; }
,
2004 (d1
, d2
) => { foreach (var couple in d2) d1.Add (couple.Key, couple.Value); return d1; }
,
2008 public static ILookup
<TKey
, TSource
> ToLookup
<TSource
, TKey
> (this ParallelQuery
<TSource
> source
,
2009 Func
<TSource
, TKey
> keySelector
)
2011 return ToLookup
<TSource
, TKey
, TSource
> (source
, keySelector
, (e
) => e
, EqualityComparer
<TKey
>.Default
);
2014 public static ILookup
<TKey
, TSource
> ToLookup
<TSource
, TKey
> (this ParallelQuery
<TSource
> source
,
2015 Func
<TSource
, TKey
> keySelector
,
2016 IEqualityComparer
<TKey
> comparer
)
2018 return ToLookup
<TSource
, TKey
, TSource
> (source
, keySelector
, (e
) => e
, comparer
);
2021 public static ILookup
<TKey
, TElement
> ToLookup
<TSource
, TKey
, TElement
> (this ParallelQuery
<TSource
> source
,
2022 Func
<TSource
, TKey
> keySelector
,
2023 Func
<TSource
, TElement
> elementSelector
)
2025 return ToLookup
<TSource
, TKey
, TElement
> (source
, keySelector
, elementSelector
, EqualityComparer
<TKey
>.Default
);
2028 public static ILookup
<TKey
, TElement
> ToLookup
<TSource
, TKey
, TElement
> (this ParallelQuery
<TSource
> source
,
2029 Func
<TSource
, TKey
> keySelector
,
2030 Func
<TSource
, TElement
> elementSelector
,
2031 IEqualityComparer
<TKey
> comparer
)
2034 throw new ArgumentNullException ("source");
2035 if (keySelector
== null)
2036 throw new ArgumentNullException ("keySelector");
2037 if (comparer
== null)
2038 comparer
= EqualityComparer
<TKey
>.Default
;
2039 if (elementSelector
== null)
2040 throw new ArgumentNullException ("elementSelector");
2042 ConcurrentLookup
<TKey
, TElement
> lookup
= new ConcurrentLookup
<TKey
, TElement
> (comparer
);
2043 source
.ForAll ((e
) => lookup
.Add (keySelector (e
), elementSelector (e
)));
2050 [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery<T> rather than "
2051 + "System.Collections.Generic.IEnumerable<T>. To fix this problem, use the AsParallel() extension method "
2052 + "to convert the right data source to System.Linq.ParallelQuery<T>.")]
2053 public static ParallelQuery
<TSource
> Concat
<TSource
>(this ParallelQuery
<TSource
> first
,
2054 IEnumerable
<TSource
> second
)
2056 throw new NotSupportedException ();
2059 public static ParallelQuery
<TSource
> Concat
<TSource
> (this ParallelQuery
<TSource
> first
, ParallelQuery
<TSource
> second
)
2061 return new ParallelQuery
<TSource
> (new QueryConcatNode
<TSource
> (first
.Node
, second
.Node
));
2065 #region DefaultIfEmpty
2066 public static ParallelQuery
<TSource
> DefaultIfEmpty
<TSource
> (this ParallelQuery
<TSource
> source
)
2068 return source
.DefaultIfEmpty (default (TSource
));
2071 public static ParallelQuery
<TSource
> DefaultIfEmpty
<TSource
> (this ParallelQuery
<TSource
> source
, TSource defaultValue
)
2073 return new ParallelQuery
<TSource
> (new QueryDefaultEmptyNode
<TSource
> (source
.Node
, defaultValue
));
2078 public static TSource First
<TSource
> (this ParallelQuery
<TSource
> source
)
2080 CancellationTokenSource src
= new CancellationTokenSource ();
2081 IEnumerator
<TSource
> enumerator
= source
.WithImplementerToken (src
).GetEnumerator ();
2083 if (enumerator
== null || !enumerator
.MoveNext ())
2084 throw new InvalidOperationException ("source contains no element");
2086 TSource result
= enumerator
.Current
;
2088 enumerator
.Dispose ();
2093 public static TSource First
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, bool> predicate
)
2095 return source
.Where (predicate
).First ();
2098 public static TSource FirstOrDefault
<TSource
> (this ParallelQuery
<TSource
> source
)
2100 return source
.DefaultIfEmpty ().First ();
2103 public static TSource FirstOrDefault
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, bool> predicate
)
2105 return source
.Where (predicate
).FirstOrDefault ();
2110 public static TSource Last
<TSource
> (this ParallelQuery
<TSource
> source
)
2112 return source
.Reverse ().First ();
2115 public static TSource Last
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, bool> predicate
)
2117 return source
.Reverse ().First (predicate
);
2120 public static TSource LastOrDefault
<TSource
> (this ParallelQuery
<TSource
> source
)
2122 return source
.Reverse ().FirstOrDefault ();
2125 public static TSource LastOrDefault
<TSource
> (this ParallelQuery
<TSource
> source
, Func
<TSource
, bool> predicate
)
2127 return source
.Reverse ().FirstOrDefault (predicate
);
2132 public static ParallelQuery
<TResult
> Zip
<TFirst
, TSecond
, TResult
> (this ParallelQuery
<TFirst
> first
,
2133 ParallelQuery
<TSecond
> second
,
2134 Func
<TFirst
, TSecond
, TResult
> resultSelector
)
2137 throw new ArgumentNullException ("first");
2139 throw new ArgumentNullException ("second");
2140 if (resultSelector
== null)
2141 throw new ArgumentNullException ("resultSelector");
2143 return new ParallelQuery
<TResult
> (new QueryZipNode
<TFirst
, TSecond
, TResult
> (resultSelector
, first
.Node
, second
.Node
));
2146 [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery<T> rather "
2147 + "than System.Collections.Generic.IEnumerable<T>. To fix this problem, use the AsParallel() "
2148 + "extension method to convert the right data source to System.Linq.ParallelQuery<T>.")]
2149 public static ParallelQuery
<TResult
> Zip
<TFirst
, TSecond
, TResult
> (this ParallelQuery
<TFirst
> first
,
2150 IEnumerable
<TSecond
> second
,
2151 Func
<TFirst
, TSecond
, TResult
> resultSelector
)
2153 throw new NotSupportedException ();