Share via


Menjeda dan meginterupsi alur

Cara paling umum untuk menyinkronkan aktivitas alur adalah dengan memblokir dan melepaskan alur, atau untuk mengunci objek atau wilayah kode. Untuk informasi selengkapnya tentang mekanisme penguncian dan pemblokiran ini, lihat Gambaran Umum Primitif Sinkronisasi.

Anda juga dapat membuat alur menjadi tidur. Ketika alur diblokir atau sedang tidur, Anda dapat menggunakan ThreadInterruptedException untuk mengeluarkannya dari status menunggu mereka.

Metode Thread.Sleep

Memanggil Thread.Sleep metode menyebabkan alur saat ini segera memblokir jumlah milidetik atau interval waktu yang Anda berikan ke metode, dan menghasilkan sisa irisan waktunya ke alur lain. Setelah interval tersebut berlalu, alur yang sedang tertidur melanjutkan eksekusi.

Satu alur tidak dapat memanggil Thread.Sleep pada alur lain. Thread.Sleep adalah metode statis yang selalu menyebabkan alur saat ini menjadi tidur.

Memanggil Thread.Sleep dengan nilai Timeout.Infinite menyebabkan alur tertidur sampai terinterupsi oleh alur lain yang memanggil Thread.Interrupt metode pada alur tertidur, atau sampai dihentikan oleh panggilan ke metode Thread.Abort-nya. Contoh berikut mengilustrasikan kedua metode menginterupsi alur tidur.

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.

Menginterupsi alur

Anda dapat menginterupsi alur yang menunggu dengan memanggil metode Thread.Interrupt pada alur yang diblokir untuk melempar ThreadInterruptedException, yang merusak alur keluar dari panggilan pemblokiran. Alur harus menangkap ThreadInterruptedException dan melakukan apa pun yang sesuai agar terus bekerja. Jika alur mengabaikan pengecualian, runtime menangkap pengecualian dan menghentikan alur.

Catatan

Jika alur target tidak diblokir saat Thread.Interrupt dipanggil, maka alur tidak terinterupsi sampai diblokir. Jika alur tidak pernah diblokir, maka ia bisa selesai tanpa pernah terinterupsi.

Jika terdapat menunggu terkelola, maka Thread.Interrupt dan Thread.Abort segera membangunkan alur. Jika menunggu tidak terkelola (misalnya, platform memanggil panggilan ke fungsi Win32 WaitForSingleObject ), baik Thread.Interrupt atau Thread.Abort tidak dapat mengontrol alur sampai kembali ke atau memanggil ke kode terkelola. Dalam kode terkelola, perilakunya adalah sebagai berikut:

Lihat juga