Skip to content

Commit 43c1138

Browse files
authored
Merge pull request #1443 from microsoft/fix1442
Fix `CancellationToken.Combine` with 3+ cancelable tokens
2 parents a6094b6 + 9e7e0ed commit 43c1138

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

src/Microsoft.VisualStudio.Threading/CancellationTokenExtensions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ public static CombinedCancellationToken CombineWith(this CancellationToken origi
115115
// Before this point we've checked every condition that would allow us to avoid it.
116116
var cancelableTokens = new CancellationToken[cancelableTokensCount];
117117
int i = 0;
118+
if (original.CanBeCanceled)
119+
{
120+
cancelableTokens[i++] = original;
121+
}
122+
118123
foreach (CancellationToken other in others)
119124
{
120125
if (other.CanBeCanceled)

test/Microsoft.VisualStudio.Threading.Tests/CancellationTokenExtensionsTests.cs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using System;
5+
using System.Linq;
56
using System.Threading;
67
using Microsoft.VisualStudio.Threading;
78
using Xunit;
@@ -226,19 +227,23 @@ public void CombineWith_Array_TwoCancelable_AmidMany(bool cancelFirst)
226227
}
227228
}
228229

229-
[Fact]
230-
public void CombineWith_Array_ThreeCancelable_AmidMany()
230+
[Theory, CombinatorialData]
231+
public void CombineWith_Array_ThreeCancelable_AmidMany([CombinatorialRange(0, 3)] int canceledIndex)
231232
{
232-
var cts1 = new CancellationTokenSource();
233-
var cts2 = new CancellationTokenSource();
234-
var cts3 = new CancellationTokenSource();
235-
using (CancellationTokenExtensions.CombinedCancellationToken combined = CancellationToken.None.CombineWith(cts1.Token, CancellationToken.None, cts2.Token, CancellationToken.None, cts3.Token))
233+
CancellationTokenSource[] cts = new CancellationTokenSource[3];
234+
for (int i = 0; i < 3; i++)
236235
{
237-
Assert.NotEqual(cts1.Token, combined.Token);
238-
Assert.NotEqual(cts2.Token, combined.Token);
239-
Assert.NotEqual(cts3.Token, combined.Token);
236+
cts[i] = new();
237+
}
240238

241-
cts2.Cancel();
239+
using (CancellationTokenExtensions.CombinedCancellationToken combined = cts[0].Token.CombineWith(cts.Skip(1).Select(s => s.Token).ToArray()))
240+
{
241+
for (int i = 0; i < cts.Length; i++)
242+
{
243+
Assert.NotEqual(cts[i].Token, combined.Token);
244+
}
245+
246+
cts[canceledIndex].Cancel();
242247
Assert.True(combined.Token.IsCancellationRequested);
243248
}
244249
}

0 commit comments

Comments
 (0)