CancellationTokenSource cancellationWithConnectTimeout = null;
if (Settings._connectTimeout != Timeout.InfiniteTimeSpan)
{
- cancellationWithConnectTimeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, default);
+ cancellationWithConnectTimeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
cancellationWithConnectTimeout.CancelAfter(Settings._connectTimeout);
cancellationToken = cancellationWithConnectTimeout.Token;
}
// Has to be called under _ThisLock lock
private CancellationToken CreateLinkedCancellationToken(CancellationToken cancellationToken)
{
- CancellationTokenSource linkedCancellationTokenSource;
-
- if (cancellationToken == CancellationToken.None)
- {
- linkedCancellationTokenSource = new CancellationTokenSource();
- }
- else
- {
- linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken,
- new CancellationTokenSource().Token);
- }
+ var linkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
Debug.Assert(_cancellationTokenSource == null, "'_cancellationTokenSource' MUST be NULL.");
_cancellationTokenSource = linkedCancellationTokenSource;
/// <summary>
/// Creates a <see cref="CancellationTokenSource"/> that will be in the canceled state
- /// when any of the source tokens are in the canceled state.
+ /// when the supplied token is in the canceled state.
/// </summary>
- /// <param name="token">The first <see cref="CancellationToken">CancellationToken</see> to observe.</param>
- /// <returns>A <see cref="CancellationTokenSource"/> that is linked to the source tokens.</returns>
- internal static CancellationTokenSource CreateLinkedTokenSource(CancellationToken token) =>
+ /// <param name="token">The <see cref="CancellationToken">CancellationToken</see> to observe.</param>
+ /// <returns>A <see cref="CancellationTokenSource"/> that is linked to the source token.</returns>
+ public static CancellationTokenSource CreateLinkedTokenSource(CancellationToken token) =>
token.CanBeCanceled ? new Linked1CancellationTokenSource(token) : new CancellationTokenSource();
/// <summary>
// We need to ensure that the Task.Delay task is appropriately cleaned up if the await
// completes due to the asyncWaiter completing, so we use our own token that we can explicitly
// cancel, and we chain the caller's supplied token into it.
- using (var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, default))
+ using (var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
{
if (asyncWaiter == await TaskFactory.CommonCWAnyLogic(new Task[] { asyncWaiter, Task.Delay(millisecondsTimeout, cts.Token) }).ConfigureAwait(false))
{
public void Cancel(bool throwOnFirstException) { }
public void CancelAfter(int millisecondsDelay) { }
public void CancelAfter(System.TimeSpan delay) { }
+ public static System.Threading.CancellationTokenSource CreateLinkedTokenSource(System.Threading.CancellationToken token) { throw null; }
public static System.Threading.CancellationTokenSource CreateLinkedTokenSource(System.Threading.CancellationToken token1, System.Threading.CancellationToken token2) { throw null; }
public static System.Threading.CancellationTokenSource CreateLinkedTokenSource(params System.Threading.CancellationToken[] tokens) { throw null; }
public void Dispose() { }
}
[Fact]
+ public static void CreateLinkedTokenSource_OneToken()
+ {
+ CancellationTokenSource original;
+
+ original = new CancellationTokenSource();
+ using (CancellationTokenSource linked = CancellationTokenSource.CreateLinkedTokenSource(original.Token))
+ {
+ Assert.False(linked.Token.IsCancellationRequested);
+ original.Cancel();
+ Assert.True(linked.Token.IsCancellationRequested);
+ }
+
+ original = new CancellationTokenSource();
+ using (CancellationTokenSource linked = CancellationTokenSource.CreateLinkedTokenSource(original.Token))
+ {
+ Assert.False(linked.Token.IsCancellationRequested);
+ linked.Cancel();
+ Assert.True(linked.Token.IsCancellationRequested);
+ Assert.False(original.IsCancellationRequested);
+ }
+
+ original = new CancellationTokenSource();
+ using (CancellationTokenSource linked = CancellationTokenSource.CreateLinkedTokenSource(original.Token))
+ {
+ Assert.False(linked.Token.IsCancellationRequested);
+ original.Dispose();
+ Assert.False(linked.Token.IsCancellationRequested);
+ }
+ }
+
+ [Fact]
public static void CreateLinkedTokenSource_Simple_TwoToken()
{
CancellationTokenSource signal1 = new CancellationTokenSource();
}
[Fact]
- public static void CreateLinkedToken_SourceTokenAlreadySignalled()
+ public static void CreateLinkedToken_SourceTokenAlreadySignalled_OneToken()
+ {
+ //creating a combined token, when a source token is already signaled.
+ CancellationTokenSource signal = new CancellationTokenSource();
+
+ signal.Cancel(); //early signal.
+
+ CancellationTokenSource combined = CancellationTokenSource.CreateLinkedTokenSource(signal.Token);
+ Assert.True(combined.IsCancellationRequested,
+ "CreateLinkedToken_SourceTokenAlreadySignalled: The combined token should immediately be in the signalled state.");
+ }
+
+ [Fact]
+ public static void CreateLinkedToken_SourceTokenAlreadySignalled_TwoTokens()
{
//creating a combined token, when a source token is already signalled.
CancellationTokenSource signal1 = new CancellationTokenSource();
// Set up teardown cancellation. We will request cancellation when a) the supplied options token
// has cancellation requested or b) when we actually complete somewhere in order to tear down
// the rest of our configured set up.
- var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, CancellationToken.None);
+ var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
Task branch1 = CreateChooseBranch<int>(cts, result, TaskScheduler.Default);
Task branch2 = CreateChooseBranch<int>(cts, result, TaskScheduler.Default);