From e65b81e3c13ec829060b1ae02b375cba712ff3c7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Feb 2026 22:39:14 +0000 Subject: [PATCH 1/4] Initial plan From 7e89e8d47e7e4a48b20f8621872a2039d4cff69f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Feb 2026 22:44:03 +0000 Subject: [PATCH 2/4] Remove deprecated Thread.Abort from pausing-and-resuming-threads article and snippets Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- .../threading/pausing-and-resuming-threads.md | 19 +++---- .../InterruptThread/InterruptThread.csproj | 10 ++++ .../csharp/InterruptThread/Program.cs | 42 +++++++++++++++ .../vb/InterruptThread/InterruptThread.vbproj | 9 ++++ .../vb/InterruptThread/Program.vb | 26 ++------- .../cs/Project.csproj | 7 --- .../cs/Sleep1.cs | 54 ------------------- 7 files changed, 73 insertions(+), 94 deletions(-) create mode 100644 docs/standard/threading/snippets/pausing-and-resuming-threads/csharp/InterruptThread/InterruptThread.csproj create mode 100644 docs/standard/threading/snippets/pausing-and-resuming-threads/csharp/InterruptThread/Program.cs create mode 100644 docs/standard/threading/snippets/pausing-and-resuming-threads/vb/InterruptThread/InterruptThread.vbproj rename samples/snippets/visualbasic/VS_Snippets_CLR/Conceptual.Threading.Resuming/vb/Sleep1.vb => docs/standard/threading/snippets/pausing-and-resuming-threads/vb/InterruptThread/Program.vb (59%) delete mode 100644 samples/snippets/csharp/VS_Snippets_CLR/Conceptual.Threading.Resuming/cs/Project.csproj delete mode 100644 samples/snippets/csharp/VS_Snippets_CLR/Conceptual.Threading.Resuming/cs/Sleep1.cs diff --git a/docs/standard/threading/pausing-and-resuming-threads.md b/docs/standard/threading/pausing-and-resuming-threads.md index cadad15431705..dd4ac7a511214 100644 --- a/docs/standard/threading/pausing-and-resuming-threads.md +++ b/docs/standard/threading/pausing-and-resuming-threads.md @@ -1,7 +1,7 @@ --- title: "Pausing and interrupting threads" description: Learn how to pause & interrupt threads in .NET. Learn how to use methods like Thread.Sleep & Thread.Interrupt, & exceptions such as ThreadInterruptedException. -ms.date: "03/30/2017" +ms.date: "02/20/2026" dev_langs: - "csharp" - "vb" @@ -10,6 +10,7 @@ helpviewer_keywords: - "threading [.NET], pausing" - "pausing threads" ms.topic: how-to +ai-usage: ai-assisted --- # Pausing and interrupting threads @@ -23,10 +24,10 @@ The most common ways to synchronize the activities of threads are to block and r One thread cannot call on another thread. is a static method that always causes the current thread to sleep. - Calling with a value of causes a thread to sleep until it is interrupted by another thread that calls the method on the sleeping thread, or until it is terminated by a call to its method. The following example illustrates both methods of interrupting a sleeping thread. - - [!code-csharp[Conceptual.Threading.Resuming#1](../../../samples/snippets/csharp/VS_Snippets_CLR/Conceptual.Threading.Resuming/cs/Sleep1.cs#1)] - [!code-vb[Conceptual.Threading.Resuming#1](../../../samples/snippets/visualbasic/VS_Snippets_CLR/Conceptual.Threading.Resuming/vb/Sleep1.vb#1)] + Calling with a value of causes a thread to sleep until another thread calls the method on the sleeping thread. The following example illustrates interrupting a sleeping thread. + +:::code language="csharp" source="./snippets/pausing-and-resuming-threads/csharp/InterruptThread/Program.cs" id="Snippet1"::: +:::code language="vb" source="./snippets/pausing-and-resuming-threads/vb/InterruptThread/Program.vb" id="Snippet1"::: ## Interrupting threads @@ -35,17 +36,13 @@ The most common ways to synchronize the activities of threads are to block and r > [!NOTE] > If the target thread is not blocked when is called, the thread is not interrupted until it blocks. If the thread never blocks, it could complete without ever being interrupted. - If a wait is a managed wait, then and both wake the thread immediately. If a wait is an unmanaged wait (for example, a platform invoke call to the Win32 [WaitForSingleObject](/windows/desktop/api/synchapi/nf-synchapi-waitforsingleobject) function), neither nor can take control of the thread until it returns to or calls into managed code. In managed code, the behavior is as follows: - -- wakes a thread out of any wait it might be in and causes a to be thrown in the destination thread. - -- .NET Framework only: wakes a thread out of any wait it might be in and causes a to be thrown on the thread. For details, see [Destroy threads](destroying-threads.md). + If a wait is a managed wait, then wakes the thread immediately. If a wait is an unmanaged wait (for example, a platform invoke call to the Win32 [WaitForSingleObject](/windows/desktop/api/synchapi/nf-synchapi-waitforsingleobject) function), can't take control of the thread until it returns to or calls into managed code. In managed code, wakes a thread out of any wait it might be in and causes a to be thrown in the destination thread. ## See also - - -- - [Threading](managed-threading-basics.md) - [Using Threads and Threading](using-threads-and-threading.md) - [Overview of Synchronization Primitives](overview-of-synchronization-primitives.md) +- [Canceling threads cooperatively](canceling-threads-cooperatively.md) diff --git a/docs/standard/threading/snippets/pausing-and-resuming-threads/csharp/InterruptThread/InterruptThread.csproj b/docs/standard/threading/snippets/pausing-and-resuming-threads/csharp/InterruptThread/InterruptThread.csproj new file mode 100644 index 0000000000000..ed9781c223ab9 --- /dev/null +++ b/docs/standard/threading/snippets/pausing-and-resuming-threads/csharp/InterruptThread/InterruptThread.csproj @@ -0,0 +1,10 @@ + + + + Exe + net10.0 + enable + enable + + + diff --git a/docs/standard/threading/snippets/pausing-and-resuming-threads/csharp/InterruptThread/Program.cs b/docs/standard/threading/snippets/pausing-and-resuming-threads/csharp/InterruptThread/Program.cs new file mode 100644 index 0000000000000..1b44088e6115b --- /dev/null +++ b/docs/standard/threading/snippets/pausing-and-resuming-threads/csharp/InterruptThread/Program.cs @@ -0,0 +1,42 @@ +// +using System; +using System.Threading; + +public class Example +{ + public static void Main() + { + // Interrupt a sleeping thread. + var sleepingThread = new Thread(SleepIndefinitely); + sleepingThread.Name = "Sleeping"; + sleepingThread.Start(); + Thread.Sleep(2000); + sleepingThread.Interrupt(); + sleepingThread.Join(); + } + + private static void SleepIndefinitely() + { + Console.WriteLine($"Thread '{Thread.CurrentThread.Name}' about to sleep indefinitely."); + try + { + Thread.Sleep(Timeout.Infinite); + } + catch (ThreadInterruptedException) + { + Console.WriteLine($"Thread '{Thread.CurrentThread.Name}' awoken."); + } + finally + { + Console.WriteLine($"Thread '{Thread.CurrentThread.Name}' executing finally block."); + } + Console.WriteLine($"Thread '{Thread.CurrentThread.Name}' finishing normal execution."); + Console.WriteLine(); + } +} +// The example displays the following output: +// Thread 'Sleeping' about to sleep indefinitely. +// Thread 'Sleeping' awoken. +// Thread 'Sleeping' executing finally block. +// Thread 'Sleeping' finishing normal execution. +// diff --git a/docs/standard/threading/snippets/pausing-and-resuming-threads/vb/InterruptThread/InterruptThread.vbproj b/docs/standard/threading/snippets/pausing-and-resuming-threads/vb/InterruptThread/InterruptThread.vbproj new file mode 100644 index 0000000000000..44b313dc839e0 --- /dev/null +++ b/docs/standard/threading/snippets/pausing-and-resuming-threads/vb/InterruptThread/InterruptThread.vbproj @@ -0,0 +1,9 @@ + + + + Exe + InterruptThread + net10.0 + + + diff --git a/samples/snippets/visualbasic/VS_Snippets_CLR/Conceptual.Threading.Resuming/vb/Sleep1.vb b/docs/standard/threading/snippets/pausing-and-resuming-threads/vb/InterruptThread/Program.vb similarity index 59% rename from samples/snippets/visualbasic/VS_Snippets_CLR/Conceptual.Threading.Resuming/vb/Sleep1.vb rename to docs/standard/threading/snippets/pausing-and-resuming-threads/vb/InterruptThread/Program.vb index 76879cccecb93..11a4e784749dc 100644 --- a/samples/snippets/visualbasic/VS_Snippets_CLR/Conceptual.Threading.Resuming/vb/Sleep1.vb +++ b/docs/standard/threading/snippets/pausing-and-resuming-threads/vb/InterruptThread/Program.vb @@ -1,25 +1,15 @@ -' Visual Basic .NET Document -Option Strict On - ' Imports System.Threading Module Example Public Sub Main() - ' Interrupt a sleeping thread. - Dim sleepingThread = New Thread(AddressOf Example.SleepIndefinitely) + ' Interrupt a sleeping thread. + Dim sleepingThread = New Thread(AddressOf SleepIndefinitely) sleepingThread.Name = "Sleeping" sleepingThread.Start() Thread.Sleep(2000) sleepingThread.Interrupt() - - Thread.Sleep(1000) - - sleepingThread = New Thread(AddressOf Example.SleepIndefinitely) - sleepingThread.Name = "Sleeping2" - sleepingThread.Start() - Thread.Sleep(2000) - sleepingThread.Abort() + sleepingThread.Join() End Sub Private Sub SleepIndefinitely() @@ -30,9 +20,6 @@ Module Example Catch ex As ThreadInterruptedException Console.WriteLine("Thread '{0}' awoken.", Thread.CurrentThread.Name) - Catch ex As ThreadAbortException - Console.WriteLine("Thread '{0}' aborted.", - Thread.CurrentThread.Name) Finally Console.WriteLine("Thread '{0}' executing finally block.", Thread.CurrentThread.Name) @@ -46,10 +33,5 @@ End Module ' Thread 'Sleeping' about to sleep indefinitely. ' Thread 'Sleeping' awoken. ' Thread 'Sleeping' executing finally block. -' Thread 'Sleeping finishing normal execution. -' -' Thread 'Sleeping2' about to sleep indefinitely. -' Thread 'Sleeping2' aborted. -' Thread 'Sleeping2' executing finally block. +' Thread 'Sleeping' finishing normal execution. ' - diff --git a/samples/snippets/csharp/VS_Snippets_CLR/Conceptual.Threading.Resuming/cs/Project.csproj b/samples/snippets/csharp/VS_Snippets_CLR/Conceptual.Threading.Resuming/cs/Project.csproj deleted file mode 100644 index f0609045a05b6..0000000000000 --- a/samples/snippets/csharp/VS_Snippets_CLR/Conceptual.Threading.Resuming/cs/Project.csproj +++ /dev/null @@ -1,7 +0,0 @@ - - - - Library - net8.0 - - diff --git a/samples/snippets/csharp/VS_Snippets_CLR/Conceptual.Threading.Resuming/cs/Sleep1.cs b/samples/snippets/csharp/VS_Snippets_CLR/Conceptual.Threading.Resuming/cs/Sleep1.cs deleted file mode 100644 index e3f512ddd04c1..0000000000000 --- a/samples/snippets/csharp/VS_Snippets_CLR/Conceptual.Threading.Resuming/cs/Sleep1.cs +++ /dev/null @@ -1,54 +0,0 @@ -// -using System; -using System.Threading; - -public class Example -{ - public static void Main() - { - // Interrupt a sleeping thread. - var sleepingThread = new Thread(Example.SleepIndefinitely); - sleepingThread.Name = "Sleeping"; - sleepingThread.Start(); - Thread.Sleep(2000); - sleepingThread.Interrupt(); - - Thread.Sleep(1000); - - sleepingThread = new Thread(Example.SleepIndefinitely); - sleepingThread.Name = "Sleeping2"; - sleepingThread.Start(); - Thread.Sleep(2000); - sleepingThread.Abort(); - } - - private static void SleepIndefinitely() - { - Console.WriteLine($"Thread '{Thread.CurrentThread.Name}' about to sleep indefinitely."); - try { - Thread.Sleep(Timeout.Infinite); - } - catch (ThreadInterruptedException) { - Console.WriteLine($"Thread '{Thread.CurrentThread.Name}' awoken."); - } - catch (ThreadAbortException) { - Console.WriteLine($"Thread '{Thread.CurrentThread.Name}' aborted."); - } - finally - { - Console.WriteLine($"Thread '{Thread.CurrentThread.Name}' executing finally block."); - } - Console.WriteLine($"Thread '{Thread.CurrentThread.Name} finishing normal execution."); - Console.WriteLine(); - } -} -// The example displays the following output: -// Thread 'Sleeping' about to sleep indefinitely. -// Thread 'Sleeping' awoken. -// Thread 'Sleeping' executing finally block. -// Thread 'Sleeping finishing normal execution. -// -// Thread 'Sleeping2' about to sleep indefinitely. -// Thread 'Sleeping2' aborted. -// Thread 'Sleeping2' executing finally block. -// From a264e20d8adb3aeb5c7462b8078315b9de9fcd25 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 20 Feb 2026 23:20:09 +0000 Subject: [PATCH 3/4] Add sentence explaining Thread.Join in the Thread.Sleep section Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/standard/threading/pausing-and-resuming-threads.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/standard/threading/pausing-and-resuming-threads.md b/docs/standard/threading/pausing-and-resuming-threads.md index dd4ac7a511214..b23f41fccb149 100644 --- a/docs/standard/threading/pausing-and-resuming-threads.md +++ b/docs/standard/threading/pausing-and-resuming-threads.md @@ -28,7 +28,9 @@ The most common ways to synchronize the activities of threads are to block and r :::code language="csharp" source="./snippets/pausing-and-resuming-threads/csharp/InterruptThread/Program.cs" id="Snippet1"::: :::code language="vb" source="./snippets/pausing-and-resuming-threads/vb/InterruptThread/Program.vb" id="Snippet1"::: - + +The example calls to block the calling thread until the interrupted thread finishes execution. + ## Interrupting threads You can interrupt a waiting thread by calling the method on the blocked thread to throw a , which breaks the thread out of the blocking call. The thread should catch the and do whatever is appropriate to continue working. If the thread ignores the exception, the runtime catches the exception and stops the thread. From 36c5af32b66e57f071f781ac824ae4d70af522eb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 24 Feb 2026 17:40:10 +0000 Subject: [PATCH 4/4] Restore .NET Framework only Thread.Abort bullet and ThreadAbortException See Also entry Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/standard/threading/pausing-and-resuming-threads.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/standard/threading/pausing-and-resuming-threads.md b/docs/standard/threading/pausing-and-resuming-threads.md index b23f41fccb149..73fc36f800860 100644 --- a/docs/standard/threading/pausing-and-resuming-threads.md +++ b/docs/standard/threading/pausing-and-resuming-threads.md @@ -38,12 +38,17 @@ The example calls [!NOTE] > If the target thread is not blocked when is called, the thread is not interrupted until it blocks. If the thread never blocks, it could complete without ever being interrupted. - If a wait is a managed wait, then wakes the thread immediately. If a wait is an unmanaged wait (for example, a platform invoke call to the Win32 [WaitForSingleObject](/windows/desktop/api/synchapi/nf-synchapi-waitforsingleobject) function), can't take control of the thread until it returns to or calls into managed code. In managed code, wakes a thread out of any wait it might be in and causes a to be thrown in the destination thread. + If a wait is a managed wait, then wakes the thread immediately. If a wait is an unmanaged wait (for example, a platform invoke call to the Win32 [WaitForSingleObject](/windows/desktop/api/synchapi/nf-synchapi-waitforsingleobject) function), can't take control of the thread until it returns to or calls into managed code. In managed code, the behavior is as follows: + +- wakes a thread out of any wait it might be in and causes a to be thrown in the destination thread. + +- .NET Framework only: wakes a thread out of any wait it might be in and causes a to be thrown on the thread. For details, see [Destroy threads](destroying-threads.md). ## See also - - +- - [Threading](managed-threading-basics.md) - [Using Threads and Threading](using-threads-and-threading.md) - [Overview of Synchronization Primitives](overview-of-synchronization-primitives.md)