Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Наиболее распространенными способами синхронизации действий потоков являются блокировка и освобождение потоков, блокировка объектов или регионов кода. Дополнительные сведения об этих механизмах запирания и блокировки см. в обзоре примитивов синхронизации.
Вы также можете поставить потоки в спящий режим. При блокировке или спящем потоке можно использовать ThreadInterruptedException, чтобы вывести их из состояния ожидания.
Метод Thread.Sleep
Вызов метода Thread.Sleep приводит к немедленному блоку текущего потока для количества миллисекунд или интервала времени, передаваемого методу, и возвращает оставшуюся часть его среза времени другому потоку. После истечения этого интервала спящий поток возобновляет выполнение.
Один поток не может вызывать Thread.Sleep в другом потоке. Thread.Sleep — это статический метод, который всегда заставляет текущий поток засыпать.
Вызов Thread.Sleep со значением Timeout.Infinite приводит к спящему потоку, пока он не будет прерван другим потоком, который вызывает метод Thread.Interrupt в спящем потоке или пока не завершится вызовом метода Thread.Abort. В следующем примере показаны оба метода прерывания спящего потока.
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.
Imports System.Threading
Module Example
Public Sub Main()
' Interrupt a sleeping thread.
Dim sleepingThread = New Thread(AddressOf Example.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()
End Sub
Private Sub SleepIndefinitely()
Console.WriteLine("Thread '{0}' about to sleep indefinitely.",
Thread.CurrentThread.Name)
Try
Thread.Sleep(Timeout.Infinite)
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)
End Try
Console.WriteLine("Thread '{0}' finishing normal execution.",
Thread.CurrentThread.Name)
Console.WriteLine()
End Sub
End Module
' 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.
Прерывание потоков
Вы можете прервать ожидающий поток, вызвав метод Thread.Interrupt в блокированном потоке для генерации ThreadInterruptedException, который выводит этот поток из блокирующего вызова. Поток должен перехватывать ThreadInterruptedException и делать все, что необходимо для продолжения работы. Если поток игнорирует исключение, среда выполнения перехватывает исключение и останавливает поток.
Примечание.
Если целевой поток не блокируется при вызове Thread.Interrupt, поток не прерывается до тех пор, пока он не блокируется. Если поток никогда не блокируется, он может завершиться без прерывания.
Если ожидание является управляемым ожиданием, то Thread.Interrupt и Thread.Abort сразу же пробуждают поток. Если ожидание является неуправляемым ожиданием (например, вызов платформы к функции Win32 WaitForSingleObject), ни Thread.Interrupt, ни Thread.Abort не может контролировать поток, пока он не возвращается в управляемый код или не вызывает его. В управляемом коде поведение выглядит следующим образом:
Thread.Interrupt выводит поток из любого состояния ожидания и вызывает выброс ThreadInterruptedException в целевом потоке.
Только .NET Framework: Thread.Abort просыпает поток из любого ожидания, в который он может находиться, и приводит к возникновению ThreadAbortException в потоке. Дополнительные сведения см. в разделе Уничтожение потоков.