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

Commit 18ff2b0

Browse files
committed
Merge pull request #2307 from Clockwork-Muse/PLINQ_ArrayCancelImmediate
PLINQ - immediate cancellation of ToArray
2 parents a6c6113 + 4dd373d commit 18ff2b0

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

src/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/QueryOperator.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,18 @@ internal TOutput[] ExecuteAndGetResultsAsArray()
209209

210210
QueryResults<TOutput> results = GetQueryResults(querySettings);
211211

212+
// Top-level preemptive cancellation test.
213+
// This handles situations where cancellation has occured before execution commences
214+
// The handling for in-execution occurs in QueryTaskGroupState.QueryEnd()
215+
216+
if (querySettings.CancellationState.MergedCancellationToken.IsCancellationRequested)
217+
{
218+
if (querySettings.CancellationState.ExternalCancellationToken.IsCancellationRequested)
219+
throw new OperationCanceledException(querySettings.CancellationState.ExternalCancellationToken);
220+
else
221+
throw new OperationCanceledException();
222+
}
223+
212224
if (results.IsIndexible && OutputOrdered)
213225
{
214226
// The special array-based merge performs better if the output is ordered, because

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,13 @@ public static IEnumerable<object[]> Ranges<T>(IEnumerable<int> counts, params Fu
190190
}
191191
}
192192

193+
// Return an enumerable which throws on first MoveNext.
194+
// Useful for testing promptness of cancellation.
195+
public static IEnumerable<object[]> ThrowOnFirstEnumeration()
196+
{
197+
yield return new object[] { Labeled.Label("ThrowOnFirstEnumeration", Enumerables<int>.ThrowOnEnumeration().AsParallel()), 8 };
198+
}
199+
193200
private static IEnumerable<Labeled<ParallelQuery<int>>> LabeledRanges(int start, int count)
194201
{
195202
yield return Labeled.Label("ParallelEnumerable.Range", ParallelEnumerable.Range(start, count));

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public static void ToArray_Longrunning(Labeled<ParallelQuery<int>> labeled, int
4848

4949
[Theory]
5050
[MemberData("Ranges", (object)(new int[] { 1 }), MemberType = typeof(Sources))]
51+
[MemberData("ThrowOnFirstEnumeration", MemberType = typeof(UnorderedSources))]
5152
public static void ToArray_OperationCanceledException_PreCanceled(Labeled<ParallelQuery<int>> labeled, int count)
5253
{
5354
CancellationTokenSource cs = new CancellationTokenSource();

0 commit comments

Comments
 (0)