Menghancurkan utas
Untuk menghentikan eksekusi utas, Anda biasanya menggunakan model pembatalan kooperatif. Namun, terkadang tidak mungkin untuk 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, Runtime Bahasa Umum melempar ThreadAbortException di utas target, yang dapat ditangkap utas target. (Namun, runtime .NET Framework selalu secara otomatis menumbuhkan kembali pengecualian setelah catch
blok.) Untuk informasi selengkapnya, lihat Thread.Abort.
Metode Thread.Abortini tidak didukung di .NET 5 (termasuk .NET Core) dan versi yang lebih baru. Jika Anda perlu menghentikan eksekusi kode pihak ketiga secara paksa di .NET 5+, jalankan dalam proses terpisah dan gunakan Process.Kill.
Catatan
- 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 ditampilkan. Anda juga tidak dapat memastikan status aplikasi Anda atau aplikasi dan status pengguna apa pun yang bertanggung jawab untuk menjaganya. Misalnya, memanggil Thread.Abort dapat mencegah eksekusi konstruktor statis atau rilis sumber daya terkelola atau tidak terkelola.
- Jika utas mengeksekusi kode tak terkelola saat metode Abort-nya dipanggil, runtime bahasa umum akan memberi tanda ThreadState.AbortRequested padanya. Pengecualian dilemparkan ketika utas kembali ke kode terkendali.
Setelah utas dibatalkan, utas tidak dapat dimulai ulang.
Metode Abort tidak menyebabkan utas segera dibatalkan, karena utas target dapat menangkap ThreadAbortException dan mengeksekusi jumlah kode arbitrer dalam blok finally
. Anda dapat memanggil Thread.Join jika Anda perlu menunggu hingga utas berakhir. Thread.Join adalah panggilan pemblokiran yang tidak kembali hingga utas benar-benar berhenti dijalankan atau interval waktu tunggu opsional telah berlalu. Utas yang dibatalkan dapat memanggil metode ResetAbort atau melakukan pemrosesan tanpa batas di blok finally
, jadi jika Anda tidak menentukan batas waktu, penungguan tidak dijamin akan berakhir.
Utas yang sedang menunggu panggilan ke metode Thread.Join dapat diinterupsi oleh utas lain yang memanggil Thread.Interrupt.
Menangani ThreadAbortException
Jika Anda menduga bahwa utas akan dibatalkan, baik sebagai akibat dari pemanggilan Abort dari kode Anda sendiri atau sebagai akibat dari membongkar domain aplikasi tempat utas berjalan (AppDomain.Unload menggunakan Thread.Abort untuk menghentikan utas), utas Anda harus menangani ThreadAbortException dan melakukan pemrosesan akhir apa pun dalam klausul 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 dalam klausul catch
atau klausul finally
, karena ThreadAbortException dilemparkan kembali oleh sistem di akhir klausul finally
, atau di akhir klausul catch
jika tidak ada klausul finally
.
Anda dapat mencegah agar sistem tidak melemparkan kembali pengecualian dengan memanggil metode Thread.ResetAbort. Namun, Anda harus melakukan ini hanya jika kode Anda sendiri yang menyebabkan ThreadAbortException.