. net >= 4.0中的StackOverflowException -给其他线程优雅退出的机会

本文关键字:线程 其他 退出 机会 StackOverflowException 中的 net | 更新日期: 2023-09-27 18:14:27

是否有一种方法如何至少推迟终止托管应用程序(通过几十毫秒)并设置一些共享标志,以使其他线程有机会优雅地终止(SO线程本身显然不会进一步执行任何内容)?我正在考虑使用JIT调试器或CLR托管-我很好奇是否有人尝试过这个。

为什么我要做一些错误的事情?:

没有太多的细节——想象一下这个类比——你在赌场赌轮盘,突然发现轮盘是不可靠的假的。所以你想立即离开赌场,但可能想先从桌子上收你的赌注。不幸的是,我不能利用单独的过程来实现这一点,因为有非常严格的性能要求。

。StackOverflowException的。NET行为(以及MSDN上的矛盾信息)已经在SO上讨论了几次-快速总结:

HandleProcessCorruptedStateExceptionsAttribute(例如在appdomain未处理的异常处理程序)不起作用

ExecuteCodeWithGuaranteedCleanup不工作

legacyUnhandledExceptionPolicy不工作

可能有一些其他的尝试如何处理stackoverflowexception -但似乎很明显CLR终止了整个过程,正如Hans Passant在这个伟大的回答中提到的。

考虑尝试:

  • JIT调试器-让线程异常冻结,设置一些共享标志(可能在固定位置)并解冻其他线程短的时间。
  • CLR托管和设置未处理的异常策略
你还有别的主意吗?或者这两种方法有成功或不成功的经验吗?

. net >= 4.0中的StackOverflowException -给其他线程优雅退出的机会

用"fake"这个词来比喻赌场不太合适。当时发生了9级地震,赌场大楼、轮盘赌桌、剩余的筹码和玩家都消失在一团巨大的烟尘中。

在SOE之后运行代码的唯一机会是远离那个赌场,它必须在另一个进程中运行。启动行为不端的程序的"保护"进程,它可以使用进程。ExitCode来检测崩溃。取值为-1073741571 (0xc00000fd)。进程状态消失后,您将不得不使用。net进程外互操作方法之一(如WCF、命名管道、套接字、内存映射文件)来使保护进程意识到需要做些什么来清理。这需要是事务性的,您无法推断崩溃发生的确切时间点,因为它可能在更新保护时死亡。

请注意,这很少值得付出努力。因为SOE与日常的进程中止几乎没有区别。比如被任务管理器杀死。或者机器失去动力。或者受到地震的影响:)

StackOverflowException是运行时无法恢复的即时和关键异常-这就是为什么您无法捕获它,或从中恢复,或其他任何东西。为了运行另一个方法(无论是清理方法还是其他方法),您必须能够为该方法创建堆栈帧,并且堆栈已经满了(这就是StackOverflowException的含义!)。您不能运行另一个方法,因为首先运行一个方法会导致异常!

不过,幸运的是,这种异常总是由程序结构引起的。您应该能够诊断并修复代码中的错误:当您获得异常时,您将在调用堆栈中看到一个或多个方法的循环无限递归。您需要确定错误的逻辑是什么并修复它,这比试图修复不可修复的异常要容易得多。