Dua sen saya di Thread.Abort dan Thread. Kaedah mengganggu

Di C #, anda mungkin perlu melepaskan utas yang telah disekat. Untuk mencapainya, terdapat dua kaedah yang boleh anda manfaatkan. Ini termasuk kaedah Thread.Abort dan Thread.Interrupt.

Apa kaedah Thread.Abort lakukan?

Untuk menamatkan utas, anda boleh memanfaatkan kaedah Abort dari kelas Thread. Perhatikan bahawa untuk memulakan proses mengakhiri utas, kaedah Abort dari kelas Thread ketika dipanggil, menimbulkan ThreadAbortException dalam utas yang telah dipanggil. Perlu diingatkan bahawa anda boleh memanfaatkan kaedah Abort dari kelas Thread untuk menamatkan thread yang tidak disekat. Sekiranya utas yang terganggu dalam keadaan menunggu, ia membangunkannya dan kemudian menyebabkan ThreadInterruptException dilemparkan. Begitu juga, jika anda memanggil kaedah Thread.Abort pada utas yang berada dalam keadaan menunggu, waktu proses membangunkan benang dan kemudian melemparkan ThreadAbortException.

Anda boleh menangkap ThreadAbortException di blok tangkapan. Walau bagaimanapun, jika anda tidak memanggil kaedah ResetAbort, pengecualian ini akan dilemparkan semula di hujung blok tangkapan. Panggilan ke kaedah ResetAbort akan menghalang ThreadAbortException daripada dilemparkan semula di hujung blok tangkapan. Berbeza dengan kaedah Thread.Inturrupt berfungsi, jika benang di mana kaedah Thread.Abort dipanggil tidak disekat, kaedah Thread.Abort melemparkan ThreadAbortException pada utas.

Dalam kebanyakan kes (melainkan jika anda ingin menutup domain aplikasi setelah utas dibatalkan), anda sama sekali tidak perlu menggunakan kaedah ini. Perhatikan bahawa kaedah Response.Redirect di ASP.Net membuang ThreadAbortException.

Apakah tujuan kaedah Thread.Interrupt?

Anda boleh menggunakan kaedah Thread.Interrupt untuk mengganggu thread yang berada dalam keadaan WaitSleepJoin. Walau bagaimanapun, tiada pendekatan ini (panggilan kaedah Thread.Abort atau Thread.Interrupt) selamat untuk thread. Walaupun kaedah Thread.Abort melemparkan ThreadAbortException, kaedah Thread.Interrupt melemparkan ThreadInterruptException. Pada dasarnya, panggilan ke kaedah Thread.Interrupt mengganggu utas dan melemparkan ThreadInterruptException untuk mengganggu utas di dalam panggilan yang menyekat. Anda harus menangani pengecualian ini dalam kod anda, yang mana runtime akan menghentikan utas yang digunakan oleh kaedah Thread.Interrupt. Perlu diingatkan bahawa panggilan ke Thread.Interrupt tidak mengganggu thread yang menjalankan kod yang tidak dikendalikan.

Pertimbangkan senarai kod berikut yang menggambarkan bagaimana kaedah Thread.Interrupt dapat dipanggil secara paksa untuk mengganggu thread.

static void Main(string[] args)

       {

           Thread thread = new Thread(ThreadMethod);

           thread.Start();

           thread.Interrupt();

           Console.Read();

       }

       private static void ThreadMethod()

       {

           try

           {

               Thread.Sleep(Timeout.Infinite);

           }

           catch (ThreadInterruptedException)

           {

             Console.Write("ThreadInterruptedException has been called forcibly.");

           }

       }

Apabila program di atas dijalankan, pesan "ThreadInterruptException telah dipanggil secara paksa" akan dipaparkan di konsol.

Apa yang berlaku jika utas yang terganggu tidak disekat? Saya membuat panggilan ke Thread. Selang pada utas yang tidak disekat, utas itu akan terus dijalankan sehingga masa disekat seterusnya. Dalam kebanyakan kes, anda tidak perlu menggunakan Thread. Ganggu sama sekali. Anda boleh mencapai yang sama menggunakan konstruk isyarat atau token pembatalan.

Sekiranya saya menggunakan kaedah Thread.Abort atau Thread.Interrupt?

Oleh itu, bilakah saya harus menggunakan kaedah Thread.Abort vs Thread. Mengganggu dalam program saya? Sekiranya saya perlu membatalkan operasi tertentu, kaedah manakah yang harus saya gunakan? Jawapan saya yang jujur ​​adalah bahawa anda tidak boleh menggunakan salah satu kaedah ini untuk menamatkan utas. Sebaiknya jangan menggunakan Thread.Abort atau Thread. Kaedah mengganggu untuk menamatkan utas - anda lebih baik memanfaatkan objek penyegerakan (seperti, WaitHandles atau Semaphores) dan melakukan penamatan benang yang anda gunakan dengan baik. Coretan kod berikut menggambarkan bagaimana anda dapat memanfaatkan WaitHandle untuk membiarkan utas berhenti dengan anggun.

private void ThreadMethod()

{

   while(!manualResetEventObject.WaitOne(TimeSpan.FromMilliseconds(100)))

   {

       //Write your code here

   }

}

Sebagai pendekatan alternatif untuk mengakhiri utas dengan baik, anda juga dapat memanfaatkan pemboleh ubah "boolean" yang tidak stabil. Anda kemudian boleh menetapkan pemboleh ubah ini dalam utas UI pada beberapa aktiviti pengguna (anggap bahawa pengguna telah mengklik butang "Batal" di UI untuk menghentikan utas) dan kemudian periksa nilai pemboleh ubah dari semasa ke semasa di Pekerja utas untuk melihat apakah pemboleh ubah telah ditetapkan (mungkin nilai "false" untuk menunjukkan penamatan benang) di antara muka pengguna.