Mina två cent på Thread.Abort och Thread.Interrupt-metoder

I C # kan du ofta behöva släppa en tråd som har blockerats. För att uppnå detta finns det två metoder som du kan dra nytta av. Dessa inkluderar metoderna Thread.Abort och Thread.Interrupt.

Vad gör Thread.Abort-metoden?

För att avsluta en tråd kan du utnyttja metoden Avbryt i trådklassen. Observera att för att starta processen för att avsluta en tråd, avbryter metoden för trådklassen när den anropas, en ThreadAbortException i den tråd som den har anropats till. Det bör noteras att du kan dra nytta av metoden Avbryt i trådklassen för att avsluta även en icke-blockerad tråd. Om tråden som avbryts är i vänteläge väcker den upp den och gör att ett ThreadInterruptedException kastas. På samma sätt, om du ringer till Thread.Abort-metoden på en tråd som är i vänteläge, väcker körtiden upp tråden och kastar sedan en ThreadAbortException.

Du kan fånga ThreadAbortException i fångstblocket. Men om du inte anropar ResetAbort-metoden kommer detta undantag att kastas igen i slutet av fångsten. Samtalet till ResetAbort-metoden kommer att förhindra att ThreadAbortException kastas om i slutet av fångblocket. I motsats till hur Thread.Inturrupt-metoderna fungerar, om tråden som Thread.Abort-metoden kallas inte blockeras, kastar Thread.Abort-metoden en ThreadAbortException på tråden.

I de flesta fall (om du inte vill stänga av applikationsdomänen efter att en tråd har avbrutits) behöver du inte använda den här metoden alls. Observera att metoden Response.Redirect i ASP.Net ger en ThreadAbortException.

Vad är syftet med Thread.Interrupt-metoden?

Du kan använda metoden Thread.Interrupt för att avbryta en tråd som är i WaitSleepJoin-tillstånd. Ingen av dessa metoder (Thread.Abort eller Thread.Interrupt method calls) är dock trådsäkra. Medan Thread.Abort-metoden kastar en ThreadAbortException, kastar Thread.Interrupt-metoden en ThreadInterruptException. I huvudsak avbryter ett samtal till Thread.Interrupt-metoden tråden och kastar en ThreadInterruptedException för att avbryta tråden inuti ett blockerande samtal. Du bör hantera detta undantag i din kod som misslyckas, vilken körtid skulle stoppa den tråd som metoden Thread.Interrupt har anropats till. Det bör noteras att ett samtal till Thread.Interrupt inte avbryter en tråd som kör ohanterad kod.

Tänk på följande kodlista som illustrerar hur Thread.Interrupt-metoden kan anropas med våld för att avbryta en tråd.

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

           }

       }

När ovanstående program körs visas meddelandet "ThreadInterruptedException har anropats med våld" i konsolen.

Vad händer om tråden som avbryts inte blockeras? Jag du ringer till tråd. Avbryt på en tråd som inte är blockerad kommer tråden att fortsätta att köra tills den blockeras nästa gång. I de flesta fall behöver du inte använda Thread.Interrupt alls. Du kan uppnå detsamma med hjälp av signalkonstruktioner eller avbokningstoken.

Ska jag använda metoden Thread.Abort eller Thread.Interrupt?

Så, när ska jag använda Thread.Abort vs Thread.Interrupt-metoder i mitt program? Om jag behöver avbryta en viss åtgärd, vilken av dessa metoder ska jag använda? Mitt ärliga svar är att du aldrig ska använda någon av dessa metoder för att avsluta en tråd. Det är tillrådligt att inte använda Thread.Abort eller Thread.Avbrottsmetoder för att avsluta en tråd - du bör hellre dra nytta av synkroniseringsobjekt (som WaitHandles eller Semaphores) och utföra en graciös avslutning av trådarna du använder. Följande kodavsnitt illustrerar hur du kan dra nytta av en WaitHandle för att låta en tråd sluta graciöst.

private void ThreadMethod()

{

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

   {

       //Write your code here

   }

}

Som ett alternativt sätt att avsluta en tråd graciöst kan du också dra nytta av en flyktig "boolesk" variabel. Du kan sedan ställa in denna variabel i användargränssnittet för någon användaraktivitet (antag att användaren har klickat på knappen "Avbryt" i användargränssnittet för att avsluta tråden) och sedan kontrollera värdet på variabeln då och då i arbetaren tråd för att se om variabeln har ställts in (kanske värdet "falskt" för att indikera avslutning av tråden) i användargränssnittet.