diff --git a/docs/standard/threading/pausing-and-resuming-threads.md b/docs/standard/threading/pausing-and-resuming-threads.md index cadad15431705..73fc36f800860 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,11 +24,13 @@ 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"::: + +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. @@ -35,11 +38,11 @@ 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, 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 @@ -49,3 +52,4 @@ The most common ways to synchronize the activities of threads are to block and r - [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. -//