【问题标题】:Extensive use of ThreadAbortExceptionThreadAbortException 的广泛使用
【发布时间】:2016-06-19 00:46:38
【问题描述】:

我在一个遗留项目中工作,该项目在许多方法中都有这种异常处理代码。

catch(ThreadAbortException e)
{
  ...
}

我在项目的任何地方都看不到 Thread.Abort() 或 Thread.Interrupt() 调用。删除所有这些 ThreadAbortException 处理是否安全,或者它是可以引发的其他方式。

【问题讨论】:

    标签: c# .net multithreading


    【解决方案1】:

    好吧,如果具体回答您的问题,我会说最好不要删除这些异常处理程序,因为它们很可能是由一些试图解决问题的开发人员添加的。而且我认为添加这些处理程序是有原因的,因此如果您只是删除此代码,它可能会导致将来再次出现一些错误。

    关于ThreadAbordException:我确信它不仅可以在您调试时调用Thread.Abort() 方法抛出(它可能是VS 中的一个错误,我不确定)并且它会强制您的程序只是默默地崩溃。因此,根据这些处理程序内部的内容,开发人员可能正在尝试解决此类问题。

    还请记住,您也可以在单独的线程中调用第三方库、Web 服务等的方法。我不确定他们是否可以抛出这样的异常,但这是一个可以考虑的情况。

    【讨论】:

      【解决方案2】:

      官方文档:“调用 Abort 方法时引发的异常。”如果您完全确定没有对 Thread.Abort 的调用,那么您不妨删除这些 catch 块。

      编辑:请注意,您的代码可能在可能在您的线程上调用 Thread.Abort 的外部应用程序的上下文中运行。

      这并不重要,因为 ThreadAbortException 无法真正处理,因为 CLR 本身会重新抛出它以实际尽快终止线程。

      “其实是的,一个ThreadAbortException是特殊的。即使你处理了它,它也会在try/catch/finally结束时被CLR自动重新抛出。(如cmets中所说,它可以被抑制使用 ResetAbort 但到那时代码闻起来像烂鱼。)” - 阅读这个问题了解更多详情:ThreadAbortException

      【讨论】:

      • @downvoter 想解释一下你为什么不赞成这个答案?
      • 不是我的反对意见,而是:您是说根据文档,抛出ThreadAbortException 的唯一方法是在调用Thread.Abort 时。首先,这是错误的:没有什么可以阻止您使用 throw 语句手动抛出 ThreadAbortException (即使它不能直接实例化,它也可以被捕获并保存)。其次,这是一种误导:虽然 OP 的代码可能不包含对 Thread.Abort 的任何直接调用,但 OP 可能正在使用调用 Thread.Abort 的外部代码,一个值得注意的例子是 Microsoft 的 IIS Web 服务器。
      • 当然你可以手动抛出它,但这样做并不意味着它是抛出异常 IIRC 有什么特别之处,不像调用 Thread.Abort 会导致 CLR 抛出尽可能多的 TAE 实例根据需要尽快杀死线程。不过,您的 IIS 评论非常有效。
      • 你说得对,手动抛出的 TAE 并不特别。不过,他们仍然会击中 OP 的 catch 块。但我必须承认,我认为发生这种情况的可能性并不高。
      【解决方案3】:

      项目是否在主线程上运行并启动后台工作线程?如果在后台线程运行时主线程退出,则后台线程可能会发生 ThreadAbortedException。

      catch 语句可以专门处理这种情况,后台线程实际上没有发生错误,其方式与任何其他异常不同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-22
        • 2012-03-27
        • 2020-02-20
        • 1970-01-01
        • 1970-01-01
        • 2010-11-27
        • 2014-07-20
        • 1970-01-01
        相关资源
        最近更新 更多