From fdf4dc9415caf94f6917aa7f7fd03d07c14c060d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Mar 2026 18:16:04 +0000 Subject: [PATCH 1/4] Initial plan From 2c9522b56e2aaf8246370b172eef91abe3c8b099 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Mar 2026 18:22:56 +0000 Subject: [PATCH 2/4] Add simple parent-child linked cancellation token example Co-authored-by: BillWagner <493969+BillWagner@users.noreply.github.com> --- .../cancellation-in-managed-threads.md | 16 +++++++--- .../csharp/LinkedTokens/LinkedTokens.csproj | 10 ++++++ .../csharp/LinkedTokens/Program.cs | 27 ++++++++++++++++ .../vb/LinkedTokens/LinkedTokens.vbproj | 9 ++++++ .../vb/LinkedTokens/Program.vb | 32 +++++++++++++++++++ 5 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 docs/standard/threading/snippets/cancellation-in-managed-threads/csharp/LinkedTokens/LinkedTokens.csproj create mode 100644 docs/standard/threading/snippets/cancellation-in-managed-threads/csharp/LinkedTokens/Program.cs create mode 100644 docs/standard/threading/snippets/cancellation-in-managed-threads/vb/LinkedTokens/LinkedTokens.vbproj create mode 100644 docs/standard/threading/snippets/cancellation-in-managed-threads/vb/LinkedTokens/Program.vb diff --git a/docs/standard/threading/cancellation-in-managed-threads.md b/docs/standard/threading/cancellation-in-managed-threads.md index 0f2d349726e17..110d566941025 100644 --- a/docs/standard/threading/cancellation-in-managed-threads.md +++ b/docs/standard/threading/cancellation-in-managed-threads.md @@ -1,7 +1,8 @@ --- title: "Cancellation in Managed Threads" description: Understand cancellation in managed threads. Learn about cancellation tokens in cooperative cancellation of asynchronous or long-running synchronous operations. -ms.date: "03/30/2017" +ms.date: "03/17/2026" +ai-usage: ai-assisted dev_langs: - "csharp" - "vb" @@ -129,14 +130,21 @@ The general pattern for implementing the cooperative cancellation model is: For a more complete example, see [How to: Listen for Cancellation Requests That Have Wait Handles](how-to-listen-for-cancellation-requests-that-have-wait-handles.md). -### Listening to Multiple Tokens Simultaneously +### Listening to multiple tokens simultaneously - In some cases, a listener may have to listen to multiple cancellation tokens simultaneously. For example, a cancelable operation may have to monitor an internal cancellation token in addition to a token passed in externally as an argument to a method parameter. To accomplish this, create a linked token source that can join two or more tokens into one token, as shown in the following example. + In some cases, a listener may have to listen to multiple cancellation tokens simultaneously. For example, a cancelable operation may have to monitor an internal cancellation token in addition to a token passed in externally as an argument to a method parameter. To accomplish this, create a linked token source that can join two or more tokens into one token. + + The following example shows the most common use of a linked token: a child operation that is cancelled whenever either the parent token or the child token is cancelled. + +:::code language="csharp" source="./snippets/cancellation-in-managed-threads/csharp/LinkedTokens/Program.cs" id="LinkedTokens"::: +:::code language="vb" source="./snippets/cancellation-in-managed-threads/vb/LinkedTokens/Program.vb" id="LinkedTokens"::: + + A more complex scenario involves a cancelable operation that must monitor both an external token passed in from a caller and an internal token. The following example shows how to create such a linked token. [!code-csharp[Cancellation#7](../../../samples/snippets/csharp/VS_Snippets_Misc/cancellation/cs/cancellationex13.cs#7)] [!code-vb[Cancellation#7](../../../samples/snippets/visualbasic/VS_Snippets_Misc/cancellation/vb/cancellationex13.vb#7)] - Notice that you must call `Dispose` on the linked token source when you are done with it. For a more complete example, see [How to: Listen for Multiple Cancellation Requests](how-to-listen-for-multiple-cancellation-requests.md). + Notice that you must call `Dispose` on the linked token source when you're done with it. For a more complete example, see [How to: Listen for Multiple Cancellation Requests](how-to-listen-for-multiple-cancellation-requests.md). ## Cooperation Between Library Code and User Code diff --git a/docs/standard/threading/snippets/cancellation-in-managed-threads/csharp/LinkedTokens/LinkedTokens.csproj b/docs/standard/threading/snippets/cancellation-in-managed-threads/csharp/LinkedTokens/LinkedTokens.csproj new file mode 100644 index 0000000000000..ed9781c223ab9 --- /dev/null +++ b/docs/standard/threading/snippets/cancellation-in-managed-threads/csharp/LinkedTokens/LinkedTokens.csproj @@ -0,0 +1,10 @@ + + + + Exe + net10.0 + enable + enable + + + diff --git a/docs/standard/threading/snippets/cancellation-in-managed-threads/csharp/LinkedTokens/Program.cs b/docs/standard/threading/snippets/cancellation-in-managed-threads/csharp/LinkedTokens/Program.cs new file mode 100644 index 0000000000000..32b2b6798b007 --- /dev/null +++ b/docs/standard/threading/snippets/cancellation-in-managed-threads/csharp/LinkedTokens/Program.cs @@ -0,0 +1,27 @@ +// +using System.Threading; + +// Create the parent CancellationTokenSource. +using var parentCts = new CancellationTokenSource(); +CancellationToken parentToken = parentCts.Token; + +// Create a linked child CancellationTokenSource. +// The child token is cancelled when the parent token is cancelled. +using var childCts = CancellationTokenSource.CreateLinkedTokenSource(parentToken); +CancellationToken childToken = childCts.Token; + +Console.WriteLine($"Parent is cancelled: {parentToken.IsCancellationRequested}"); +Console.WriteLine($"Child is cancelled: {childToken.IsCancellationRequested}"); + +// Cancel the parent. +parentCts.Cancel(); + +Console.WriteLine($"Parent is cancelled: {parentToken.IsCancellationRequested}"); +Console.WriteLine($"Child is cancelled: {childToken.IsCancellationRequested}"); + +// Output: +// Parent is cancelled: False +// Child is cancelled: False +// Parent is cancelled: True +// Child is cancelled: True +// diff --git a/docs/standard/threading/snippets/cancellation-in-managed-threads/vb/LinkedTokens/LinkedTokens.vbproj b/docs/standard/threading/snippets/cancellation-in-managed-threads/vb/LinkedTokens/LinkedTokens.vbproj new file mode 100644 index 0000000000000..a49398a9bb1ef --- /dev/null +++ b/docs/standard/threading/snippets/cancellation-in-managed-threads/vb/LinkedTokens/LinkedTokens.vbproj @@ -0,0 +1,9 @@ + + + + Exe + LinkedTokens + net10.0 + + + diff --git a/docs/standard/threading/snippets/cancellation-in-managed-threads/vb/LinkedTokens/Program.vb b/docs/standard/threading/snippets/cancellation-in-managed-threads/vb/LinkedTokens/Program.vb new file mode 100644 index 0000000000000..a36d775eda5c2 --- /dev/null +++ b/docs/standard/threading/snippets/cancellation-in-managed-threads/vb/LinkedTokens/Program.vb @@ -0,0 +1,32 @@ +' +Imports System.Threading + +Module Program + Sub Main() + ' Create the parent CancellationTokenSource. + Using parentCts As New CancellationTokenSource() + Dim parentToken As CancellationToken = parentCts.Token + + ' Create a linked child CancellationTokenSource. + ' The child token is cancelled when the parent token is cancelled. + Using childCts As CancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(parentToken) + Dim childToken As CancellationToken = childCts.Token + + Console.WriteLine($"Parent is cancelled: {parentToken.IsCancellationRequested}") + Console.WriteLine($"Child is cancelled: {childToken.IsCancellationRequested}") + + ' Cancel the parent. + parentCts.Cancel() + + Console.WriteLine($"Parent is cancelled: {parentToken.IsCancellationRequested}") + Console.WriteLine($"Child is cancelled: {childToken.IsCancellationRequested}") + End Using + End Using + End Sub +End Module +' Output: +' Parent is cancelled: False +' Child is cancelled: False +' Parent is cancelled: True +' Child is cancelled: True +' From 5bfc489af4d125b2d84241c501ca275865c3972d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Mar 2026 22:01:05 +0000 Subject: [PATCH 3/4] Fix intro text for linked token example per review feedback Co-authored-by: BillWagner <493969+BillWagner@users.noreply.github.com> --- docs/standard/threading/cancellation-in-managed-threads.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/standard/threading/cancellation-in-managed-threads.md b/docs/standard/threading/cancellation-in-managed-threads.md index 110d566941025..f0dc4b327e6d8 100644 --- a/docs/standard/threading/cancellation-in-managed-threads.md +++ b/docs/standard/threading/cancellation-in-managed-threads.md @@ -132,9 +132,9 @@ The general pattern for implementing the cooperative cancellation model is: ### Listening to multiple tokens simultaneously - In some cases, a listener may have to listen to multiple cancellation tokens simultaneously. For example, a cancelable operation may have to monitor an internal cancellation token in addition to a token passed in externally as an argument to a method parameter. To accomplish this, create a linked token source that can join two or more tokens into one token. + In some cases, a listener might have to listen to multiple cancellation tokens simultaneously. For example, a cancelable operation might have to monitor an internal cancellation token in addition to a token passed in externally as an argument to a method parameter. To accomplish this, create a linked token source that can join two or more tokens into one token. - The following example shows the most common use of a linked token: a child operation that is cancelled whenever either the parent token or the child token is cancelled. + The following example shows the most common use of a linked token: a child token that is cancelled when the parent token is cancelled. You can also cancel the child independently by calling `Cancel` on the child `CancellationTokenSource`. :::code language="csharp" source="./snippets/cancellation-in-managed-threads/csharp/LinkedTokens/Program.cs" id="LinkedTokens"::: :::code language="vb" source="./snippets/cancellation-in-managed-threads/vb/LinkedTokens/Program.vb" id="LinkedTokens"::: From 1b6968555879b5cb8ef9b575ae678a7e5187e573 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Thu, 19 Mar 2026 08:32:21 -0400 Subject: [PATCH 4/4] Update docs/standard/threading/cancellation-in-managed-threads.md Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- docs/standard/threading/cancellation-in-managed-threads.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/standard/threading/cancellation-in-managed-threads.md b/docs/standard/threading/cancellation-in-managed-threads.md index f0dc4b327e6d8..3b21c6080c2b8 100644 --- a/docs/standard/threading/cancellation-in-managed-threads.md +++ b/docs/standard/threading/cancellation-in-managed-threads.md @@ -130,7 +130,7 @@ The general pattern for implementing the cooperative cancellation model is: For a more complete example, see [How to: Listen for Cancellation Requests That Have Wait Handles](how-to-listen-for-cancellation-requests-that-have-wait-handles.md). -### Listening to multiple tokens simultaneously +### Listen to multiple tokens simultaneously In some cases, a listener might have to listen to multiple cancellation tokens simultaneously. For example, a cancelable operation might have to monitor an internal cancellation token in addition to a token passed in externally as an argument to a method parameter. To accomplish this, create a linked token source that can join two or more tokens into one token.