Moja dva centa na metodi Thread.Abort i Thread.Netourrupt

U C # ćete često trebati otpustiti nit koja je blokirana. Da biste to postigli, postoje dvije metode koje možete iskoristiti. Uključuju metode Thread.Abort i Thread.Interrupt.

Što radi metoda Thread.Abort?

Da biste prekinuli nit, možete iskoristiti metodu Abort klase Thread. Imajte na umu da za pokretanje postupka završetka niti, metoda Abort klase Thread kada se pozove, podiže ThreadAbortException u niti u kojoj je pozvana. Treba napomenuti da možete iskoristiti metodu Abort klase Thread da biste prekinuli čak i neblokiranu nit. Ako je nit koja se prekida u stanju čekanja, probudi je, a zatim uzrokuje bacanje ThreadInterruptedException. Slično tome, ako metodu Thread.Abort pozovete na niti koja je u stanju čekanja, vrijeme izvođenja budi nit, a zatim baca ThreadAbortException.

ThreadAbortException možete uhvatiti u bloku catch. Međutim, ako ne pozovete ResetAbort metodu, ova će se iznimka ponovno baciti na kraju bloka catch. Poziv metode ResetAbort spriječit će ponovno izbacivanje ThreadAbortException na kraju bloka catch. Suprotno načinu rada metoda Thread.Inturrupt, ako nit na kojoj se poziva metoda Thread.Abort nije blokirana, metoda Thread.Abort baca ThreadAbortException na nit.

U većini slučajeva (osim ako ne želite isključiti domenu aplikacije nakon prekida niti), uopće ne morate koristiti ovu metodu. Napominjemo da metoda Response.Redirect u ASP.Netu baca ThreadAbortException.

Koja je svrha metode Thread.Interrupt?

Možete koristiti metodu Thread.Interrupt da biste prekinuli nit koja je u stanju WaitSleepJoin. Međutim, niti jedan od ovih pristupa (pozivi metode Thread.Abort ili Thread.Interrupt) nije zaštićen niti. Dok metoda Thread.Abort baca ThreadAbortException, metoda Thread.Interrupt baca ThreadInterruptException. U osnovi, poziv Thread.Interrupt metode prekida nit i baca ThreadInterruptedException kako bi prekinuo nit unutar poziva blokiranja. Ovu biste iznimku trebali riješiti u svom kodu, a ako izvršavanje zaustavi nit na kojoj je pozvana metoda Thread.Interrupt. Treba imati na umu da poziv na Thread.Interrupt ne prekida nit koja izvršava neupravljani kôd.

Razmotrite sljedeći popis kodova koji ilustrira kako se metoda Thread.Interrupt može prisilno pozvati da prekine nit.

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.");

           }

       }

Kada se izvrši gornji program, na konzoli će se prikazati poruka "ThreadInterruptedException je prisilno pozvan".

Što se događa ako nit koja se prekida nije blokirana? Ako uputite poziv Threadu. Prekid na niti koja nije blokirana, nit će se nastaviti izvršavati sve dok sljedeća ne bude blokirana. U većini slučajeva uopće ne trebate koristiti Thread.Interrupt. To možete postići pomoću signalnih konstrukcija ili žetona za otkazivanje.

Trebam li koristiti metodu Thread.Abort ili Thread.Interrupt?

Pa, kada trebam koristiti metode Thread.Abort vs Thread.Interrupt u svom programu? Ako trebam otkazati određenu operaciju, koju od ovih metoda trebam koristiti? Moj iskren odgovor je da nikada ne biste trebali koristiti bilo koju od ovih metoda za prekidanje niti. Preporučljivo je ne koristiti metode Thread.Abort ili Thread.Interrupt za prekidanje niti - radije biste trebali iskoristiti objekte sinkronizacije (poput WaitHandles ili Semaphores) i izvršiti graciozno prekidanje niti koje koristite. Sljedeći isječak koda ilustrira kako možete iskoristiti WaitHandle kako biste omogućili niti da se graciozno zaustavi.

private void ThreadMethod()

{

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

   {

       //Write your code here

   }

}

Kao alternativni pristup za graciozno završavanje niti, također možete iskoristiti nestabilnu "logičku" varijablu. Zatim možete postaviti ovu varijablu u niti korisničkog sučelja na neku korisničku aktivnost (pretpostavimo da je korisnik kliknuo gumb "Odustani" u korisničkom sučelju da bi prekinuo nit), a zatim s vremena na vrijeme provjeriti vrijednost varijable u radniku nit da vidi je li varijabla postavljena (možda vrijednost "false" da označava prekid niti) u korisničkom sučelju.