Bagikan melalui


Menghentikan thread

Untuk mengakhiri eksekusi utas, Anda biasanya menggunakan model pembatalan kooperatif. Namun, terkadang tidak dapat menghentikan utas secara kooperatif, karena menjalankan kode pihak ketiga yang tidak dirancang untuk pembatalan kooperatif. Di aplikasi .NET Framework, Anda dapat menggunakan Thread.Abort metode untuk mengakhiri utas terkelola secara paksa. Saat Anda memanggil Abort, Common Language Runtime melemparkan ThreadAbortException di utas target, yang dapat ditangkap oleh utas target tersebut. (Namun, runtime .NET Framework selalu secara otomatis melempar ulang pengecualian setelah di blok catch.) Untuk informasi selengkapnya, lihat Thread.Abort.

Metode Thread.Abort melemparkan PlatformNotSupportedException pada runtime di .NET Core, .NET 5, dan versi yang lebih baru. Mulai dari .NET 5, itu juga ditandai usang (SYSLIB0006), jadi memanggilnya menghasilkan peringatan waktu kompilasi. Jika Anda perlu mengakhiri eksekusi kode pihak ketiga secara paksa dalam implementasi .NET modern, jalankan dalam proses terpisah dan gunakan Process.Kill.

Nota

  • Saat Anda memanggil Thread.Abort untuk membatalkan utas selain utas saat ini, Anda tidak tahu kode apa yang telah dijalankan atau gagal dijalankan saat ThreadAbortException dilemparkan. Anda juga tidak dapat memastikan status aplikasi Anda, atau setiap aplikasi dan status pengguna yang perlu dipertahankan. Misalnya, panggilan Thread.Abort dapat mencegah eksekusi konstruktor statis atau rilis sumber daya terkelola atau tidak terkelola.
  • Jika utas mengeksekusi kode tidak terkelola ketika metodenya Abort dipanggil, runtime menandainya ThreadState.AbortRequested. Pengecualian dilemparkan ketika utas kembali ke kode terkelola.

Setelah utas dibatalkan, itu tidak dapat dimulai ulang.

Metode Abort tidak menyebabkan utas dibatalkan segera, karena utas target dapat menangkap ThreadAbortException dan dapat menjalankan sejumlah kode sembarang dalam blok finally. Anda dapat memanggil Thread.Join jika Anda perlu menunggu hingga thread selesai. Thread.Join adalah panggilan pemblokiran yang tidak kembali sampai utas benar-benar berhenti dieksekusi atau interval batas waktu opsional telah berlalu. Utas yang dibatalkan dapat memanggil ResetAbort metode atau melakukan pemrosesan tidak terbatas dalam finally blok, jadi jika Anda tidak menentukan batas waktu, waktu tunggu tidak dijamin berakhir.

Utas yang menunggu panggilan ke Thread.Join metode dapat terganggu oleh utas lain yang memanggil Thread.Interrupt.

Menangani ThreadAbortException

Jika Anda mengharapkan utas Anda dibatalkan, baik sebagai akibat dari panggilan Abort dari kode Anda sendiri atau sebagai akibat dari memuat keluar domain aplikasi tempat utas berjalan (AppDomain.Unload menggunakan Thread.Abort untuk mengakhiri utas), utas Anda harus menangani ThreadAbortException dan melakukan pemrosesan akhir dalam klausula finally, seperti yang ditunjukkan dalam kode berikut.

Try  
    ' Code that is executing when the thread is aborted.  
Catch ex As ThreadAbortException  
    ' Clean-up code can go here.  
    ' If there is no Finally clause, ThreadAbortException is  
    ' re-thrown by the system at the end of the Catch clause.
Finally  
    ' Clean-up code can go here.  
End Try  
' Do not put clean-up code here, because the exception
' is rethrown at the end of the Finally clause.  
try
{  
    // Code that is executing when the thread is aborted.  
}
catch (ThreadAbortException ex)
{  
    // Clean-up code can go here.  
    // If there is no Finally clause, ThreadAbortException is  
    // re-thrown by the system at the end of the Catch clause.
}  
// Do not put clean-up code here, because the exception
// is rethrown at the end of the Finally clause.  

Kode pembersihan Anda harus berada dalam catch klausul atau finally klausul, karena ThreadAbortException dilempar kembali oleh sistem di akhir finally klausul, atau di akhir catch klausul jika tidak ada finally klausul.

Anda dapat mencegah sistem melempar kembali pengecualian dengan memanggil metode Thread.ResetAbort. Namun, Anda harus melakukan ini hanya jika kode Anda sendiri menyebabkan ThreadAbortException.

Baca juga