Dela via


Förstöra trådar

Om du vill avsluta körningen av tråden använder du vanligtvis modellen för kooperativ annullering. Ibland går det dock inte att stoppa en tråd kooperativt, eftersom den kör kod från tredje part som inte är utformad för kooperativ annullering. I .NET Framework-appar kan du använda Thread.Abort metoden för att avsluta en hanterad tråd med tvång. När du anropar Abortgenererar Common Language Runtime en ThreadAbortException i måltråden, som måltråden kan fånga. (.NET Framework-körningen återställer dock alltid automatiskt undantaget efter catch blocket.) Mer information finns i Thread.Abort.

Metoden Thread.Abortstöds inte i .NET 5 (inklusive .NET Core) och senare versioner. Om du behöver avsluta körningen av kod från tredje part med två skäl i .NET 5+, kör du den i den separata processen och använder Process.Kill.

Kommentar

  • När du anropar Thread.Abort för att avbryta en annan tråd än den aktuella tråden vet du inte vilken kod som har körts eller inte kunde köras när den ThreadAbortException genereras. Du kan inte heller vara säker på tillståndet för ditt program eller något program och användartillstånd som det är ansvarigt för att bevara. Anrop Thread.Abort kan till exempel förhindra körning av statiska konstruktorer eller frisläppning av hanterade eller ohanterade resurser.
  • Om en tråd kör ohanterad kod när dess Abort metod anropas markerar körningen den ThreadState.AbortRequested. Undantaget utlöses när tråden återgår till hanterad kod.

När en tråd har avbrutits kan den inte startas om.

Metoden Abort gör inte att tråden avbryts omedelbart, eftersom måltråden kan fånga ThreadAbortException upp och köra godtyckliga mängder kod i ett finally block. Du kan anropa Thread.Join om du behöver vänta tills tråden har avslutats. Thread.Join är ett blockeringsanrop som inte returneras förrän tråden faktiskt har slutat köras eller ett valfritt tidsgränsintervall har förflutit. Den avbrutna tråden ResetAbort kan anropa metoden eller utföra obundna bearbetningar i ett finally block, så om du inte anger någon tidsgräns är väntetiden inte garanterad att avslutas.

Trådar som väntar på ett anrop till Thread.Join metoden kan avbrytas av andra trådar som anropar Thread.Interrupt.

Hantera ThreadAbortException

Om du förväntar dig att tråden ska avbrytas, antingen som ett resultat av anrop Abort från din egen kod eller som ett resultat av att en programdomän där tråden körs (AppDomain.Unload används Thread.Abort för att avsluta trådar), måste tråden ThreadAbortException hantera och utföra eventuell slutlig bearbetning i en finally -sats, som visas i följande kod.

Try  
    ' Code that is executing when the thread is aborted.  
Catch ex As ThreadAbortException  
    ' Clean-up code can go here.  
    ' If there is no Finally clause, ThreadAbortException is  
    ' re-thrown by the system at the end of the Catch clause.
Finally  
    ' Clean-up code can go here.  
End Try  
' Do not put clean-up code here, because the exception
' is rethrown at the end of the Finally clause.  
try
{  
    // Code that is executing when the thread is aborted.  
}
catch (ThreadAbortException ex)
{  
    // Clean-up code can go here.  
    // If there is no Finally clause, ThreadAbortException is  
    // re-thrown by the system at the end of the Catch clause.
}  
// Do not put clean-up code here, because the exception
// is rethrown at the end of the Finally clause.  

Din rensningskod måste finnas i catch -satsen eller finally -satsen, eftersom en ThreadAbortException återaktiveras av systemet i slutet av finally -satsen eller i slutet av catch -satsen om det inte finns någon finally -sats.

Du kan förhindra att systemet återaktiverar undantaget genom att anropa Thread.ResetAbort metoden. Du bör dock bara göra detta om din egen kod orsakade ThreadAbortException.

Se även