Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 0034eef

Browse files
Remove unused cancelled token check, fix PLINQ version of #2239
1 parent a6c6113 commit 0034eef

File tree

5 files changed

+117
-86
lines changed

5 files changed

+117
-86
lines changed

src/System.Linq.Parallel/src/System/Linq/Parallel/Utils/ReverseComparer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ internal ReverseComparer(IComparer<T> comparer)
2727

2828
public int Compare(T x, T y)
2929
{
30-
return -_comparer.Compare(x, y);
30+
return _comparer.Compare(y, x);
3131
}
3232
}
3333
}

src/System.Linq.Parallel/src/System/Linq/ParallelEnumerable.cs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -352,29 +352,10 @@ public static ParallelQuery<TSource> WithDegreeOfParallelism<TSource>(this Paral
352352
/// <exception cref="T:System.InvalidOperationException">
353353
/// WithCancellation is used multiple times in the query.
354354
/// </exception>
355-
/// <exception cref="T:System.ObjectDisposedException">
356-
/// The <see cref="T:System.Threading.CancellationTokenSource"/> associated with the <paramref name="cancellationToken"/> has been disposed.
357-
/// </exception>
358355
public static ParallelQuery<TSource> WithCancellation<TSource>(this ParallelQuery<TSource> source, CancellationToken cancellationToken)
359356
{
360357
if (source == null) throw new ArgumentNullException("source");
361358

362-
// also a convenience check whether the cancellationTokenSource backing the token is already disposed.
363-
// do this via a dummy registration as there is no public IsDipsosed property on CT.
364-
CancellationTokenRegistration dummyRegistration = new CancellationTokenRegistration();
365-
try
366-
{
367-
dummyRegistration = cancellationToken.Register(() => { });
368-
}
369-
catch (ObjectDisposedException)
370-
{
371-
throw new ArgumentException(SR.ParallelEnumerable_WithCancellation_TokenSourceDisposed, "cancellationToken");
372-
}
373-
finally
374-
{
375-
dummyRegistration.Dispose();
376-
}
377-
378359
QuerySettings settings = QuerySettings.Empty;
379360
settings.CancellationState = new CancellationState(cancellationToken);
380361

src/System.Linq.Parallel/tests/Helpers/Comparers.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,24 @@ public int Compare(int x, int y)
7272
}
7373
}
7474

75+
/// <summary>
76+
/// Returns an extreme value from non-equal comparisons.
77+
/// </summary>
78+
/// <remarks>Helper for regression test against PLINQ's version of #2239 .</remarks>
79+
/// <typeparam name="T">The type being compared.</typeparam>
80+
internal class ExtremeComparer<T> : IComparer<T>
81+
{
82+
private IComparer<T> _def = Comparer<T>.Default;
83+
84+
public int Compare(T x, T y)
85+
{
86+
int direction = _def.Compare(x, y);
87+
return direction == 0 ? 0 :
88+
direction > 0 ? int.MaxValue :
89+
int.MinValue;
90+
}
91+
}
92+
7593
internal static class DelgatedComparable
7694
{
7795
public static DelegatedComparable<T> Delegate<T>(T value, IComparer<T> comparer) where T : IComparable<T>

src/System.Linq.Parallel/tests/QueryOperators/OrderByThenByTests.cs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,55 @@ public static void OrderByDescending_NotPipelined_CustomComparator_Longrunning(L
326326
OrderByDescending_NotPipelined_CustomComparer(labeled, count);
327327
}
328328

329+
[Theory]
330+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(Sources))]
331+
[MemberData("OrderByRandomData", (object)(new[] { 0, 1, 2, 16 }))]
332+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(UnorderedSources))]
333+
// Regression test for the PLINQ version of #2239 - comparer returning max/min value.
334+
public static void OrderBy_ExtremeComparer(Labeled<ParallelQuery<int>> labeled, int count)
335+
{
336+
int prev = int.MinValue;
337+
foreach (int i in labeled.Item.OrderBy(x => x, new ExtremeComparer<int>()))
338+
{
339+
Assert.InRange(i, prev, int.MaxValue);
340+
prev = i;
341+
}
342+
}
343+
344+
[Theory]
345+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(Sources))]
346+
[MemberData("OrderByRandomData", (object)(new[] { 0, 1, 2, 16 }))]
347+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(UnorderedSources))]
348+
// Regression test for the PLINQ version of #2239 - comparer returning max/min value.
349+
public static void OrderByDescending_ExtremeComparer(Labeled<ParallelQuery<int>> labeled, int count)
350+
{
351+
int prev = int.MaxValue;
352+
foreach (int i in labeled.Item.OrderByDescending(x => x, new ExtremeComparer<int>()))
353+
{
354+
Assert.InRange(i, int.MinValue, prev);
355+
prev = i;
356+
}
357+
}
358+
359+
[Theory]
360+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(Sources))]
361+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(UnorderedSources))]
362+
public static void OrderBy_NotPipelined_ExtremeComparer(Labeled<ParallelQuery<int>> labeled, int count)
363+
{
364+
int prev = int.MinValue;
365+
Assert.All(labeled.Item.OrderBy(x => x, new ExtremeComparer<int>()).ToList(), x => { Assert.InRange(x, prev, int.MaxValue); prev = x; });
366+
}
367+
368+
[Theory]
369+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(Sources))]
370+
[MemberData("OrderByRandomData", (object)(new[] { 0, 1, 2, 16 }))]
371+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(UnorderedSources))]
372+
public static void OrderByDescending_NotPipelined_ExtremeComparer(Labeled<ParallelQuery<int>> labeled, int count)
373+
{
374+
int prev = int.MaxValue;
375+
Assert.All(labeled.Item.OrderByDescending(x => x, new ExtremeComparer<int>()).ToList(), x => { Assert.InRange(x, int.MinValue, prev); prev = x; });
376+
}
377+
329378
[Fact]
330379
public static void OrderBy_ArgumentNullException()
331380
{
@@ -753,6 +802,55 @@ public static void ThenByDescending_NotPipelined_CustomComparator_Longrunning(La
753802
ThenByDescending_NotPipelined_CustomComparer(labeled, count);
754803
}
755804

805+
[Theory]
806+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(Sources))]
807+
[MemberData("OrderByRandomData", (object)(new[] { 0, 1, 2, 16 }))]
808+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(UnorderedSources))]
809+
// Regression test for the PLINQ version of #2239 - comparer returning max/min value.
810+
public static void ThenBy_ExtremeComparer(Labeled<ParallelQuery<int>> labeled, int count)
811+
{
812+
int prev = int.MinValue;
813+
foreach (int i in labeled.Item.OrderBy(x => 0).ThenBy(x => x, new ExtremeComparer<int>()))
814+
{
815+
Assert.InRange(i, prev, int.MaxValue);
816+
prev = i;
817+
}
818+
}
819+
820+
[Theory]
821+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(Sources))]
822+
[MemberData("OrderByRandomData", (object)(new[] { 0, 1, 2, 16 }))]
823+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(UnorderedSources))]
824+
// Regression test for the PLINQ version of #2239 - comparer returning max/min value.
825+
public static void ThenByDescending_ExtremeComparer(Labeled<ParallelQuery<int>> labeled, int count)
826+
{
827+
int prev = int.MaxValue;
828+
foreach (int i in labeled.Item.OrderBy(x => 0).ThenByDescending(x => x, new ExtremeComparer<int>()))
829+
{
830+
Assert.InRange(i, int.MinValue, prev);
831+
prev = i;
832+
}
833+
}
834+
835+
[Theory]
836+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(Sources))]
837+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(UnorderedSources))]
838+
public static void ThenBy_NotPipelined_ExtremeComparer(Labeled<ParallelQuery<int>> labeled, int count)
839+
{
840+
int prev = int.MinValue;
841+
Assert.All(labeled.Item.OrderBy(x => 0).ThenBy(x => x, new ExtremeComparer<int>()).ToList(), x => { Assert.InRange(x, prev, int.MaxValue); prev = x; });
842+
}
843+
844+
[Theory]
845+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(Sources))]
846+
[MemberData("OrderByRandomData", (object)(new[] { 0, 1, 2, 16 }))]
847+
[MemberData("Ranges", (object)(new int[] { 0, 1, 2, 16 }), MemberType = typeof(UnorderedSources))]
848+
public static void ThenByDescending_NotPipelined_ExtremeComparer(Labeled<ParallelQuery<int>> labeled, int count)
849+
{
850+
int prev = int.MaxValue;
851+
Assert.All(labeled.Item.OrderBy(x => 0).ThenByDescending(x => x, new ExtremeComparer<int>()).ToList(), x => { Assert.InRange(x, int.MinValue, prev); prev = x; });
852+
}
853+
756854
// Recursive sort with nested ThenBy...s
757855
// Due to the use of randomized input, cycles will not start with a known input (and may skip values, etc).
758856

src/System.Linq.Parallel/tests/WithCancellationTests.cs

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -617,71 +617,5 @@ public static void DontDoWorkIfTokenAlreadyCanceled()
617617

618618
Assert.NotNull(oce);
619619
}
620-
621-
// To help the user, we will check if a cancellation token passed to WithCancellation() is
622-
// not backed by a disposed CTS. This will help them identify incorrect cts.Dispose calls, but
623-
// doesn't solve all their problems if they don't manage CTS lifetime correctly.
624-
// We test via a few random queries that have shown inconsistent behavior in the past.
625-
[Fact]
626-
public static void PreDisposedCTSPassedToPlinq()
627-
{
628-
ArgumentException ae1 = null;
629-
ArgumentException ae2 = null;
630-
ArgumentException ae3 = null;
631-
632-
CancellationTokenSource cts = new CancellationTokenSource();
633-
CancellationToken ct = cts.Token;
634-
cts.Dispose(); // Early dispose
635-
try
636-
{
637-
Enumerable.Range(1, 10).AsParallel()
638-
.WithCancellation(ct)
639-
.OrderBy(x => x)
640-
.ToArray();
641-
}
642-
catch (Exception ex)
643-
{
644-
// This is not going to be the case since we changed the behavior of WithCancellation
645-
// to not throw when called on disposed cancellationtokens.
646-
ae1 = (ArgumentException)ex;
647-
}
648-
649-
try
650-
{
651-
Enumerable.Range(1, 10).AsParallel()
652-
.WithCancellation(ct)
653-
.Last();
654-
}
655-
catch (Exception ex)
656-
{
657-
// This is not going to be the case since we changed the behavior of WithCancellation
658-
// to not throw when called on disposed cancellationtokens.
659-
ae2 = (ArgumentException)ex;
660-
}
661-
662-
try
663-
{
664-
Enumerable.Range(1, 10).AsParallel()
665-
.WithCancellation(ct)
666-
.OrderBy(x => x)
667-
.Last();
668-
}
669-
catch (Exception ex)
670-
{
671-
// This is not going to be the case since we changed the behavior of WithCancellation
672-
// to not throw when called on disposed cancellationtokens.
673-
ae3 = (ArgumentException)ex;
674-
}
675-
676-
Assert.Null(ae1);
677-
Assert.Null(ae2);
678-
Assert.Null(ae3);
679-
}
680-
681-
public static void SimulateThreadSleep(int milliseconds)
682-
{
683-
ManualResetEvent mre = new ManualResetEvent(false);
684-
mre.WaitOne(milliseconds);
685-
}
686620
}
687621
}

0 commit comments

Comments
 (0)