Programování

Moje dva centy za metody Thread.Abort a Thread.Interrupt

V C # možná budete muset uvolnit vlákno, které bylo zablokováno. K dosažení tohoto cíle můžete využít dvě metody. Patří mezi ně metody Thread.Abort a Thread.Interrupt.

Co dělá metoda Thread.Abort?

Chcete-li vlákno ukončit, můžete využít metodu Abort třídy Thread. Všimněte si, že k zahájení procesu ukončení vlákna Abort metoda třídy Thread při vyvolání vyvolá ThreadAbortException ve vlákně, na kterém byla volána. Je třeba poznamenat, že můžete využít metodu Abort třídy Thread k ukončení i neblokovaného vlákna. Pokud je vlákno, které je přerušeno, ve stavu čekání, probudí ho a způsobí vyvolání ThreadInterruptedException. Podobně, pokud zavoláte metodu Thread.Abort na vlákno, které je ve stavu čekání, modul runtime probudí vlákno a poté vyvolá ThreadAbortException.

ThreadAbortException můžete zachytit v bloku catch. Pokud však nevoláte metodu ResetAbort, bude tato výjimka znovu vyvolána na konci bloku zachycení. Volání metody ResetAbort zabrání tomu, aby byla ThreadAbortException znovu vyvolána na konci bloku zachycení. Na rozdíl od toho, jak Thread.Inturrupt metody fungují, pokud není blokováno vlákno, na kterém je volána metoda Thread.Abort, Thread.Abort metoda vyvolá ThreadAbortException na vlákno.

Ve většině případů (pokud byste nechtěli vypnout doménu aplikace po přerušení vlákna), nemusíte tuto metodu používat vůbec. Všimněte si, že metoda Response.Redirect v ASP.Net vyvolá ThreadAbortException.

Jaký je účel metody Thread.Interrupt?

Metodu Thread.Interrupt můžete použít k přerušení vlákna, které je ve stavu WaitSleepJoin. Žádný z těchto přístupů (volání metody Thread.Abort nebo Thread.Interrupt) však není bezpečný pro vlákna. Zatímco Thread.Abort metoda vyvolá ThreadAbortException, Thread.Interrupt metoda vyvolá ThreadInterruptException. V podstatě volání metody Thread.Interrupt přeruší vlákno a vyvolá ThreadInterruptedException, aby přerušilo vlákno uvnitř blokujícího volání. Tuto výjimku byste měli zpracovat v selhání svého kódu, což by běhové prostředí zastavilo vlákno, na kterém byla volána metoda Thread.Interrupt. Je třeba poznamenat, že volání Thread.Interrupt neruší vlákno, které provádí nespravovaný kód.

Zvažte následující výpis kódu, který ilustruje, jak lze Thread.Interrupt metodu vyvolat násilně, aby se vlákno přerušilo.

static void Main (řetězec [] args)

       {

Thread thread = new Thread (ThreadMethod);

thread.Start ();

thread.Interrupt ();

Console.Read ();

       }

private static void ThreadMethod ()

       {

Snaž se

           {

Thread.Sleep (Timeout.Infinite);

           }

chytit (ThreadInterruptedException)

           {

Console.Write ("ThreadInterruptedException byl vyvolán násilně.");

           }

       }

Když je spuštěn výše uvedený program, zobrazí se v konzole zpráva „ThreadInterruptedException was called násilně“.

Co se stane, pokud není přerušované vlákno blokováno? Zavolám Thread.Interrupt na vlákně, které není blokováno, vlákno bude pokračovat v provádění, dokud nebude blokováno další. Ve většině případů nemusíte Thread.Interrupt vůbec používat. Totéž můžete dosáhnout pomocí signalizačních konstrukcí nebo tokenů zrušení.

Mám použít metodu Thread.Abort nebo Thread.Interrupt?

Kdy bych tedy měl ve svém programu použít metody Thread.Abort vs Thread.Interrupt? Pokud potřebuji zrušit určitou operaci, kterou z těchto metod mám použít? Moje upřímná odpověď je, že byste nikdy neměli používat žádnou z těchto metod k ukončení vlákna. Doporučuje se nepoužívat metody Thread.Abort nebo Thread.Interrupt k ukončení vlákna - měli byste raději využít výhod synchronizačních objektů (jako jsou WaitHandles nebo Semaphores) a provést půvabné ukončení vláken, která používáte. Následující fragment kódu ukazuje, jak můžete využít WaitHandle k povolení řádného zastavení vlákna.

private void ThreadMethod ()

{

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

   {

// Sem napište kód

   }

}

Jako alternativní přístup k řádnému ukončení vlákna můžete také využít těkavou proměnnou typu „boolean“. Poté můžete tuto proměnnou ve vlákně uživatelského rozhraní nastavit na nějakou aktivitu uživatele (předpokládejme, že uživatel klikl na tlačítko „Zrušit“ v uživatelském rozhraní a vlákno ukončí) a poté v Workeru čas od času zkontrolovat hodnotu proměnné vlákno, abyste zjistili, zda byla proměnná nastavena (možná hodnota „false“ pro označení ukončení vlákna) v uživatelském rozhraní.