【问题标题】:What is the least graceful way to stop a .NET thread?停止 .NET 线程的最不优雅的方法是什么?
【发布时间】:2011-03-22 16:10:53
【问题描述】:

我正在测试一些错误处理代码,并试图确保我的应用程序和数据始终无法进入一致状态。我已经验证了代码适用于注入错误的“正常”方式,但我想更进一步。

杀死 .NET 线程的最突然的方法是什么,使错误处理的机会最少?

例如,您将如何测试 CLR 约束执行区域的限制?或者我将如何模拟像拔掉插头这样严重的事情?

【问题讨论】:

  • 从轨道上用核弹发射它。
  • 拔下电脑。
  • @John Rasch 尽管抛出异常很实用,但我必须承认很少有场景像立即断电那样戏剧性。
  • 从任务管理器中杀死进程。
  • 也许您可以通过在虚拟机中运行并突然关闭它来模拟电源故障...

标签: c# .net error-handling


【解决方案1】:

导致堆栈溢出异常 - 无法捕获。只需编写一个调用自身的函数即可。

【讨论】:

  • 我喜欢,这很严肃。知道如何将其注入另一个线程吗?
  • 你的意思是,注入?线程从调用委托开始,代码从那里开始。您需要编写线程,以便它在某些时候调用无限递归的东西。
【解决方案2】:

您可以调用/调用TerminateThread windows API 函数。但这很有可能破坏程序中的非托管状态,包括 CLR 本身的状态。因此,执行此操作后,您的进程处于未定义状态,终止整个进程可能是个好主意。

【讨论】:

    【解决方案3】:

    如果你有线程的句柄,你可以调用 Thread.Abort(); 这会在被调用线程上引发 ThreadAbortedException。

    【讨论】:

    • 我已经做到了,但是如果系统内存不足并且无法实例化 ThreadAbortedException 怎么办?我将如何模拟那种级别的东西?
    • 这将执行finally 子句,所以它不是很突然。甚至可能根本不会终止线程。
    • 如果你内存不足,无论如何你很快就会崩溃.. :) 在那之后你无能为力
    • @JasonRShaver - 如果由于内存不足而无法实例化异常,那么我猜该程序的许多其他部分也会由于内存不足而失败。因此,如果您已经在测试一般内存不足,那么我认为在正常情况下一个简单的 Thread.Abort() 就足够了。
    • @CodeInChaos - 非常好。即使你没有刻意为ThreadAbortedException 写一个catch,你也可以写一个finally 块,它会抛出另一个异常,然后你会捕获它!
    【解决方案4】:

    您可以使用 Thread.Abort。这将在线程上强制抛出 ThreadAbortedException。

    最有力的方法,除了切断电源,当然是从任务管理器中杀死进程。

    【讨论】:

      【解决方案5】:

      不终止整个进程的唯一方法是通过调用 TerminateThread() 来阻止 catch 和 finally 块的执行。这是一个有问题的功能,只能在测试场景中使用。它泄漏了为堆栈分配的内存。您也很难获得所需的线程句柄。这需要调用 GetCurrentThread(),这必须从线程本身内部完成。

      在此之后,您的测试程序的状态是随机的,就像您使用 Thread.Abort() 时一样。好吧,更糟。

      【讨论】:

        【解决方案6】:

        Thread.Abort 被认为是邪恶的。一种可能的方法是拥有一个对工作人员和调用者都可见的 volatile 布尔值(来源:http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation

        【讨论】:

        • 我认为他想要一些邪恶的东西来测试他的程序如何处理它。
        • 我还将添加注释,Thread.Abort 会导致 C# 中的内存链接,这正是我有兴趣测试的那种东西。
        猜你喜欢
        • 2019-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多