Programovanie

Moje dva centy za metódy Thread.Abort a Thread.Interrupt

V C # možno budete musieť uvoľniť blokované vlákno. Aby ste to dosiahli, môžete využiť dve metódy. Patria sem metódy Thread.Abort a Thread.Interrupt.

Čo robí metóda Thread.Abort?

Na ukončenie vlákna môžete využiť metódu Abort triedy Thread. Upozorňujeme, že na spustenie procesu ukončenia vlákna spôsobí metóda Abort triedy Thread pri vyvolaní ThreadAbortException vo vlákne, na ktoré bola volaná. Je potrebné poznamenať, že môžete využiť metódu Abort triedy Thread na ukončenie dokonca aj neblokovaného vlákna. Ak je vlákno, ktoré sa prerušuje, v stave čakania, prebudí ho a potom spôsobí vyvolanie ThreadInterruptedException. Podobne, ak zavoláte metódu Thread.Abort na vlákno, ktoré je v stave čakania, modul runtime vlákno prebudí a potom vyvolá ThreadAbortException.

ThreadAbortException môžete zachytiť v bloku catch. Ak však metódu ResetAbort nezavoláte, táto výnimka sa znovu hodí na konci bloku catch. Volanie metódy ResetAbort zabráni tomu, aby sa ThreadAbortException opätovne hodila na koniec bloku chytenia. Na rozdiel od toho, ako fungujú metódy Thread.Inturrupt, ak nie je blokované vlákno, na ktorom sa volá metóda Thread.Abort, metóda Thread.Abort vrhá na vlákno ThreadAbortException.

Vo väčšine prípadov (pokiaľ nechcete doménu aplikácie vypnúť po prerušení vlákna), nemusíte túto metódu používať vôbec. Všimnite si, že metóda Response.Redirect v ASP.Net vyvolá ThreadAbortException.

Aký je účel metódy Thread.Interrupt?

Môžete použiť metódu Thread.Interrupt na prerušenie vlákna, ktoré je v stave WaitSleepJoin. Žiadny z týchto prístupov (volania metód Thread.Abort alebo Thread.Interrupt) však nie je bezpečný z hľadiska vlákien. Zatiaľ čo metóda Thread.Abort hodí ThreadAbortException, metóda Thread.Interrupt vyvolá ThreadInterruptException. V podstate volanie metódy Thread.Interrupt preruší vlákno a vyvolá ThreadInterruptedException, aby prerušilo vlákno vo vnútri blokujúceho hovoru. Túto výnimku by ste mali spracovať v prípade, že váš kód zlyhá, čím runtime zastaví vlákno, na ktorom bola volaná metóda Thread.Interrupt. Je potrebné poznamenať, že volanie Thread.Interrupt neruší vlákno, ktoré vykonáva nespravovaný kód.

Zvážte nasledujúci zoznam kódov, ktorý ilustruje, ako možno metódu Thread.Interrupt vyvolať násilne, aby prerušila vlákno.

static void Main (reťazec [] args)

       {

Závit vlákna = nové vlákno (ThreadMethod);

závit.Start ();

závit.Interrupt ();

Console.Read ();

       }

private static void ThreadMethod ()

       {

skús

           {

Thread.Sleep (Timeout.Infinite);

           }

chytiť (ThreadInterruptedException)

           {

Console.Write ("ThreadInterruptedException bola volaná násilne.");

           }

       }

Keď sa vykoná vyššie uvedený program, v konzole sa zobrazí správa „Násilne sa zavolala ThreadInterruptedException“.

Čo sa stane, ak vlákno, ktoré je prerušované, nie je blokované? Zavoláte na vlákno. Prerušenie na vlákne, ktoré nie je blokované, vlákno sa bude naďalej vykonávať, kým nebude blokované najbližšie. Vo väčšine prípadov nemusíte Thread.Interrupt používať vôbec. To isté môžete dosiahnuť pomocou signalizačných konštruktov alebo zrušovacích tokenov.

Mám použiť metódu Thread.Abort alebo Thread.Interrupt?

Kedy by som mal v mojom programe použiť metódy Thread.Abort vs Thread.Interrupt? Ak potrebujem zrušiť určitú operáciu, ktorý z týchto spôsobov by som mal použiť? Moja úprimná odpoveď je, že nikdy by ste nemali používať žiadnu z týchto metód na ukončenie vlákna. Odporúča sa nepoužívať metódy Thread.Abort alebo Thread.Interrupt na ukončenie vlákna - mali by ste radšej využiť výhody synchronizačných objektov (ako sú WaitHandles alebo Semaphores) a vykonať elegantné ukončenie použitých vlákien. Nasledujúci úryvok kódu ilustruje, ako môžete využiť WaitHandle na umožnenie elegantného zastavenia vlákna.

private void ThreadMethod ()

{

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

   {

// Sem napíš svoj kód

   }

}

Ako alternatívny prístup na elegantné ukončenie vlákna môžete využiť aj volatilnú „booleovskú“ premennú. Túto premennú potom môžete nastaviť vo vlákne používateľského rozhrania na určitú aktivitu používateľov (predpokladajme, že používateľ klikol na tlačidlo „Zrušiť“ v používateľskom rozhraní, aby sa vlákno ukončilo) a potom z času na čas v nástroji Worker skontrolujte hodnotu premennej vlákno, aby ste zistili, či bola premenná nastavená (možno hodnota „false“ na označenie ukončenia vlákna) v používateľskom rozhraní.

$config[zx-auto] not found$config[zx-overlay] not found