Zničit vlákna
K ukončení provádění vlákna obvykle používáte model družstevního zrušení. Někdy však není možné zastavit vlákno kooperativně, protože spouští kód třetí strany, který není určený pro kooperativní zrušení. V aplikacích .NET Framework můžete metodu použít Thread.Abort k ukončení spravovaného vlákna vynuceně. Při volání Abortvyvolá modul CLR (Common Language Runtime) v cílovém ThreadAbortException vlákně, které cílové vlákno může zachytit. (Modul runtime rozhraní .NET Framework však vždy automaticky znovu zvětšuje výjimku po catch
bloku.) Další informace naleznete v tématu Thread.Abort.
Metoda není podporována Thread.Abort v .NET 5 (včetně .NET Core) a novějších verzích. Pokud potřebujete ukončit provádění kódu třetí strany vynuceně v .NET 5+, spusťte ho v samostatném procesu a použijte Process.Kill.
Poznámka:
- Když zavoláte Thread.Abort přerušení vlákna jiného než aktuálního vlákna, nevíte, jaký kód se spustil nebo se nepodařilo provést při ThreadAbortException vyvolání. Také nemůžete mít jistotu o stavu vaší aplikace nebo žádné aplikace a stavu uživatele, za které odpovídá za zachování. Volání Thread.Abort může například zabránit spuštění statických konstruktorů nebo uvolnění spravovaných nebo nespravovaných prostředků.
- Pokud vlákno spouští nespravovaný kód při zavolání jeho Abort metody, modul runtime ho ThreadState.AbortRequestedoznačí . Výjimka se vyvolá, když se vlákno vrátí do spravovaného kódu.
Jakmile je vlákno přerušeno, nelze ho restartovat.
Metoda Abort nezpůsobí přerušení vlákna okamžitě, protože cílové vlákno může zachytit ThreadAbortException a spustit libovolné množství kódu v finally
bloku. Pokud potřebujete počkat, až vlákno skončí, můžete volat Thread.Join . Thread.Join je blokující volání, které se nevrací, dokud vlákno skutečně nezastaví provádění nebo nepovinný interval časového limitu uplynul. Přerušené vlákno může volat metodu ResetAbort nebo provádět nevázané zpracování v finally
bloku, takže pokud nezadáte časový limit, čekání není zaručeno ukončení.
Vlákna čekající na volání Thread.Join metody mohou být přerušena jinými vlákny, která volají Thread.Interrupt.
Zpracování threadAbortException
Pokud očekáváte, že vaše vlákno bude přerušeno, buď v důsledku volání Abort z vlastního kódu, nebo v důsledku uvolnění domény aplikace, ve které je vlákno spuštěno (AppDomain.Unload používá Thread.Abort se k ukončení vláken), musí vlákno zpracovat ThreadAbortException a provést jakékoli konečné zpracování v finally
klauzuli, jak je znázorněno v následujícím kódu.
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.
Váš kód čištění musí být v catch
klauzuli nebo finally
klauzuli, protože ThreadAbortException systém na konci finally
klauzule znovu otěhotná, nebo na konci catch
klauzule, pokud neexistuje žádná finally
klauzule.
Systému můžete zabránit v opětovném načítání výjimky voláním Thread.ResetAbort metody. To byste však měli provést pouze v případě, že váš vlastní kód způsobil ThreadAbortException.