Wstrzymywanie i przerywanie wątków
Najczęstsze sposoby synchronizowania działań wątków to blokowanie i zwalnianie wątków albo blokowanie obiektów lub regionów kodu. Aby uzyskać więcej informacji na temat tych mechanizmów blokowania i blokowania, zobacz Omówienie elementów pierwotnych synchronizacji.
Można również mieć wątki umieścić się spać. Gdy wątki są blokowane lub śpią, możesz użyć elementu , ThreadInterruptedException aby przerwać je ze stanów oczekiwania.
Metoda Thread.Sleep
Thread.Sleep Wywołanie metody powoduje natychmiastowe zablokowanie bieżącego wątku dla liczby milisekund lub interwału czasu przekazywanego do metody i zwraca resztę fragmentu czasu do innego wątku. Po upływie tego interwału wątek uśpienia wznawia wykonywanie.
Jeden wątek nie może wywołać Thread.Sleep innego wątku. Thread.Sleep jest metodą statyczną, która zawsze powoduje uśpienie bieżącego wątku.
Wywołanie Thread.Sleep z wartością powoduje uśpienie wątku Timeout.Infinite , dopóki nie zostanie przerwany przez inny wątek, który wywołuje Thread.Interrupt metodę w wątku uśpienia lub dopóki nie zostanie przerwany przez wywołanie metody Thread.Abort . Poniższy przykład ilustruje obie metody przerywania wątku uśpienia.
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 '{0}' about to sleep indefinitely.",
Thread.CurrentThread.Name);
try {
Thread.Sleep(Timeout.Infinite);
}
catch (ThreadInterruptedException) {
Console.WriteLine("Thread '{0}' awoken.",
Thread.CurrentThread.Name);
}
catch (ThreadAbortException) {
Console.WriteLine("Thread '{0}' aborted.",
Thread.CurrentThread.Name);
}
finally
{
Console.WriteLine("Thread '{0}' executing finally block.",
Thread.CurrentThread.Name);
}
Console.WriteLine("Thread '{0} finishing normal execution.",
Thread.CurrentThread.Name);
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.
Przerywanie wątków
Możesz przerwać wątek oczekiwania, wywołując Thread.Interrupt metodę w zablokowanym wątku, aby zgłosić ThreadInterruptedExceptionelement , który przerywa wątek z wywołania blokującego. Wątek powinien przechwytywać ThreadInterruptedException i robić wszystko, co jest właściwe, aby kontynuować pracę. Jeśli wątek ignoruje wyjątek, środowisko uruchomieniowe przechwytuje wyjątek i zatrzymuje wątek.
Uwaga
Jeśli wątek docelowy nie zostanie zablokowany po Thread.Interrupt wywołaniu, wątek nie zostanie przerwany, dopóki nie zostanie zablokowany. Jeśli wątek nigdy nie blokuje, może zakończyć się bez przerywania.
Jeśli oczekiwanie jest zarządzane, a następnie Thread.Interrupt Thread.Abort oba wybudzą wątek natychmiast. Jeśli oczekiwanie jest niezarządzanym oczekiwaniem (na przykład wywołanie platformy do funkcji Win32 WaitForSingleObject ), ani Thread.Interrupt Thread.Abort nie może przejąć kontroli nad wątkiem, dopóki nie powróci do kodu zarządzanego lub wywoła go. W kodzie zarządzanym zachowanie jest następujące:
Thread.Interrupt Budzi wątek z dowolnego oczekiwania może być w i powoduje, że ThreadInterruptedException element zostanie wyrzucony w wątku docelowym.
Tylko program .NET Framework: Thread.Abort wznawia wątek z dowolnego oczekiwania, w którym może występować, i powoduje ThreadAbortException , że element zostanie zgłoszony w wątku. Aby uzyskać szczegółowe informacje, zobacz Niszczenie wątków.