Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions docs/standard/threading/pausing-and-resuming-threads.md
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -10,6 +10,7 @@ helpviewer_keywords:
- "threading [.NET], pausing"
- "pausing threads"
ms.topic: how-to
ai-usage: ai-assisted
---
# Pausing and interrupting threads

Expand All @@ -23,29 +24,27 @@ The most common ways to synchronize the activities of threads are to block and r

One thread cannot call <xref:System.Threading.Thread.Sleep%2A?displayProperty=nameWithType> on another thread. <xref:System.Threading.Thread.Sleep%2A?displayProperty=nameWithType> is a static method that always causes the current thread to sleep.

Calling <xref:System.Threading.Thread.Sleep%2A?displayProperty=nameWithType> with a value of <xref:System.Threading.Timeout.Infinite?displayProperty=nameWithType> causes a thread to sleep until it is interrupted by another thread that calls the <xref:System.Threading.Thread.Interrupt%2A?displayProperty=nameWithType> method on the sleeping thread, or until it is terminated by a call to its <xref:System.Threading.Thread.Abort%2A?displayProperty=nameWithType> 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 <xref:System.Threading.Thread.Sleep%2A?displayProperty=nameWithType> with a value of <xref:System.Threading.Timeout.Infinite?displayProperty=nameWithType> causes a thread to sleep until another thread calls the <xref:System.Threading.Thread.Interrupt%2A?displayProperty=nameWithType> 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 <xref:System.Threading.Thread.Join%2A?displayProperty=nameWithType> to block the calling thread until the interrupted thread finishes execution.

## Interrupting threads

You can interrupt a waiting thread by calling the <xref:System.Threading.Thread.Interrupt%2A?displayProperty=nameWithType> method on the blocked thread to throw a <xref:System.Threading.ThreadInterruptedException>, which breaks the thread out of the blocking call. The thread should catch the <xref:System.Threading.ThreadInterruptedException> and do whatever is appropriate to continue working. If the thread ignores the exception, the runtime catches the exception and stops the thread.

> [!NOTE]
> If the target thread is not blocked when <xref:System.Threading.Thread.Interrupt%2A?displayProperty=nameWithType> 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 <xref:System.Threading.Thread.Interrupt%2A?displayProperty=nameWithType> and <xref:System.Threading.Thread.Abort%2A?displayProperty=nameWithType> 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 <xref:System.Threading.Thread.Interrupt%2A?displayProperty=nameWithType> nor <xref:System.Threading.Thread.Abort%2A?displayProperty=nameWithType> can take control of the thread until it returns to or calls into managed code. In managed code, the behavior is as follows:

- <xref:System.Threading.Thread.Interrupt%2A?displayProperty=nameWithType> wakes a thread out of any wait it might be in and causes a <xref:System.Threading.ThreadInterruptedException> to be thrown in the destination thread.

- .NET Framework only: <xref:System.Threading.Thread.Abort%2A?displayProperty=nameWithType> wakes a thread out of any wait it might be in and causes a <xref:System.Threading.ThreadAbortException> to be thrown on the thread. For details, see [Destroy threads](destroying-threads.md).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we keep the .NET Framework info?

If a wait is a managed wait, then <xref:System.Threading.Thread.Interrupt%2A?displayProperty=nameWithType> 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), <xref:System.Threading.Thread.Interrupt%2A?displayProperty=nameWithType> can't take control of the thread until it returns to or calls into managed code. In managed code, <xref:System.Threading.Thread.Interrupt%2A?displayProperty=nameWithType> wakes a thread out of any wait it might be in and causes a <xref:System.Threading.ThreadInterruptedException> to be thrown in the destination thread.

## See also

- <xref:System.Threading.Thread>
- <xref:System.Threading.ThreadInterruptedException>
- <xref:System.Threading.ThreadAbortException>
- [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)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// <Snippet1>
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.
// </Snippet1>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<RootNamespace>InterruptThread</RootNamespace>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
' Visual Basic .NET Document
Option Strict On

' <Snippet1>
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()
Expand All @@ -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)
Expand All @@ -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.
' </Snippet1>

This file was deleted.

This file was deleted.