trydex Asked:2020-12-26 18:43:45 +0000 UTC2020-12-26 18:43:45 +0000 UTC 2020-12-26 18:43:45 +0000 UTC 如何用无限循环杀死线程并处理 ThreadAbortException 772 有没有办法杀死正在运行此方法的线程? public static void M() { while (true) { try { } catch (ThreadAbortException) { Thread.ResetAbort(); } } } c# 2 个回答 Voted freim 2020-12-26T19:29:00Z2020-12-26T19:29:00Z 有一种方法可以强制线程结束,尽管 MS 不建议这样做太粗鲁。这是TerminateThread 函数。 它需要一个线程句柄作为参数,可以先通过 ManagedThreadId 识别线程来获取,然后通过OpenThread函数获取句柄。WinAPI IDIDWinAPI Best Answer iluxa1810 2020-12-26T19:35:23Z2020-12-26T19:35:23Z 您可以使用属性SecurityPermission。 例如,使用这种方法,在尝试执行时会出现糟糕的情况Thread.ResetAbort(); static void Main(string[] args) { var thread = new Thread(SomeMethod); thread.Start(); Thread.Sleep(5000); thread.Abort(); while (thread.IsAlive) { } Console.WriteLine("Готово"); Console.ReadKey(); } [SecurityPermission(SecurityAction.PermitOnly, ControlThread = false)] public static void SomeMethod() { while (true) { try { Thread.Sleep(1000); Console.WriteLine("1"); } catch (Exception e) { Thread.ResetAbort(); } } } 但是,带有未处理异常的线程的死亡意味着整个应用程序的死亡=>将所有内容包装在一个全局中try/catch,围绕来自不受信任来源的方法。 但是这样的线程不会死: static void Main(string[] args) { var thread = new Thread(SomeMethod); thread.Start(); Thread.Sleep(2000); thread.Abort(); while (thread.IsAlive) { Thread.Sleep(2000); thread.Abort(); } Console.WriteLine("Готово"); Console.ReadKey(); } [SecurityPermission(SecurityAction.PermitOnly, ControlThread = false)] public static void SomeMethod() { try { while (true) { try { Thread.Sleep(1000); Console.WriteLine("1"); } catch (Exception e) { try { Thread.ResetAbort(); } catch (Exception exception) { while (true) { Thread.Sleep(1000); Console.WriteLine("2"); } } } } } catch (Exception e) { Console.WriteLine(e); } } 执行ResetAbort线程中断,但处理异常并在无限循环中旋转。多次尝试Abort从主线程调用不起作用。流量还在继续…… 虽然,还有另一种更正确的解决方案 - 应用程序域 ( AppDomain),它仅用于来自不受信任源的代码。 如果我们将不安全的代码加载到单独的域中,那么它将成功地在卸载域时中断,打喷嚏Thread.ResetAbort();: public class TestClass : MarshalByRefObject { public void SomeMethod() { while (true) { try { Thread.Sleep(1000); Console.WriteLine("1"); } catch (Exception e) { try { Thread.ResetAbort(); } catch (Exception exception) { while (true) { Thread.Sleep(1000); Console.WriteLine("2"); } } } } } } class Program { static void Main(string[] args) { AppDomain domain = AppDomain.CreateDomain("MyDomain"); var t=(TestClass)domain.CreateInstanceAndUnwrap(typeof(TestClass).Assembly.FullName, typeof(TestClass).FullName); Task.Run(() => t.SomeMethod()); Thread.Sleep(2000); AppDomain.Unload(domain); Console.ReadKey(); } } 根据 Richter 的说法,这就是机制的工作原理SQL CLR,MS SQL SERVER它可以防止程序集调用Thread.RestAbort().
有一种方法可以强制线程结束,尽管 MS 不建议这样做太粗鲁。这是TerminateThread
函数。 它需要一个线程句柄作为参数,可以先通过 ManagedThreadId 识别线程来获取,然后通过OpenThread函数获取句柄。
WinAPIIDIDWinAPI您可以使用属性
SecurityPermission。例如,使用这种方法,在尝试执行时会出现糟糕的情况
Thread.ResetAbort();但是,带有未处理异常的线程的死亡意味着整个应用程序的死亡=>将所有内容包装在一个全局中
try/catch,围绕来自不受信任来源的方法。但是这样的线程不会死:
执行
ResetAbort线程中断,但处理异常并在无限循环中旋转。多次尝试Abort从主线程调用不起作用。流量还在继续……虽然,还有另一种更正确的解决方案 - 应用程序域 (
AppDomain),它仅用于来自不受信任源的代码。如果我们将不安全的代码加载到单独的域中,那么它将成功地在卸载域时中断,打喷嚏
Thread.ResetAbort();:根据 Richter 的说法,这就是机制的工作原理
SQL CLR,MS SQL SERVER它可以防止程序集调用Thread.RestAbort().