C# .NET中的StackOverflowException>;=4.0-给其他线程正常退出的机会

C# .NET中的StackOverflowException>;=4.0-给其他线程正常退出的机会,c#,stack-overflow,clr-hosting,postmortem-debugging,C#,Stack Overflow,Clr Hosting,Postmortem Debugging,有没有办法至少推迟托管应用程序的终止(几十毫秒),并设置一些共享标志,让其他线程有机会正常终止(这样线程本身就不会执行任何进一步的操作)?我正在考虑使用JIT调试器或CLR托管来实现这一点——如果以前有人尝试过,我会很好奇 我为什么要做这样错误的事?: 没有太多细节-想象一下这个类比-你在赌场赌轮盘赌,突然发现轮盘赌不可靠。因此,您希望立即离开赌场,但可能希望首先从赌桌上收回您的赌注。 不幸的是,我不能利用单独的过程来实现这一点,因为有非常严格的性能要求 尝试但未成功: StackOverflo

有没有办法至少推迟托管应用程序的终止(几十毫秒),并设置一些共享标志,让其他线程有机会正常终止(这样线程本身就不会执行任何进一步的操作)?我正在考虑使用JIT调试器或CLR托管来实现这一点——如果以前有人尝试过,我会很好奇

我为什么要做这样错误的事?:

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

尝试但未成功:

StackOverflowException的.NET行为(以及MSDN上的矛盾信息)已在SO上讨论过多次,以快速总结:

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

不起作用

不起作用

可能很少有其他尝试来处理StackOverflowException,但是很明显,正如Hans Passant在中提到的,CLR终止了整个过程

正在考虑尝试:

  • JIT调试器-将异常线程保持为冻结状态,设置一些 共享标志(可能位于固定位置)并解冻其他线程以获取 时间很短
  • CLR宿主和设置未处理的异常策略

你还有别的想法吗?或者这两种方法的任何经验(成功/不成功)

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


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

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

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

对于您的赌场类比,“假”一词并不完全正确。发生了里氏9级地震,赌场大楼连同轮盘赌桌、剩余的筹码和玩家消失在巨大的烟尘中

在SOE之后运行代码的唯一方法是远离赌场,它必须在另一个进程中运行。启动行为不端程序的“guard”进程,它可以使用process.ExitCode检测崩溃。它将是-1073741571(0xc00000fd)。进程状态消失后,您必须使用一种.NET进程外互操作方法(如WCF、命名管道、套接字、内存映射文件)使guard进程知道需要进行清理的操作。这需要是事务性的,您无法解释崩溃发生的确切时间点,因为它可能在更新防护时死亡

一定要小心,这是很少值得的努力。因为SOE与日常流程中止是很难区分的。就像被任务经理杀死一样。或者机器失去动力。或者正在遭受地震的影响:)

用“假”这个词来比喻赌场是不太正确的。发生了里氏9级地震,赌场大楼连同轮盘赌桌、剩余的筹码和玩家消失在巨大的烟尘中

在SOE之后运行代码的唯一方法是远离赌场,它必须在另一个进程中运行。启动行为不端程序的“guard”进程,它可以使用process.ExitCode检测崩溃。它将是-1073741571(0xc00000fd)。进程状态消失后,您必须使用一种.NET进程外互操作方法(如WCF、命名管道、套接字、内存映射文件)使guard进程知道需要进行清理的操作。这需要是事务性的,您无法解释崩溃发生的确切时间点,因为它可能在更新防护时死亡

一定要小心,这是很少值得的努力。因为SOE与日常流程中止是很难区分的。就像被任务经理杀死一样。或者机器失去动力。或者受到地震的影响:)

堆栈溢出并不总是由程序结构引起的,它