当前位置: 首页 > 编程语言 > C#

为什么ExecuteCodeWithGuaranteedCleanup不起作用?Share

时间:2023-04-11 11:03:45 C#

为什么ExecuteCodeWithGuaranteedCleanup不起作用?我正在尝试“测量”堆栈深度。为什么下面的程序不打印任何东西?类程序{privatestaticintDepth=0;staticvoidA(objecto){深度++;一个(o);}staticvoidB(objecto,boole){Console.WriteLine(Depth);[]args){RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(A,B,null);}}一些答案仅包含来自MSDN的引述,例如“从.NETFramework2.0版开始,StackOverflowException对象不能被try-catch块捕获,并且默认情况下将终止相应的进程。”相信我,有时(当有足够的堆栈空间时)它可以被忽略,下面打印一些数字就好了:classProgram{privatestaticintdepth=0;staticvoidA(objecto){depth++;if(Environment.StackTrace.Length>8000)thrownewStackOverflowException("Catchmeifyoucan.");一个(o);}staticvoidB(objecto,boole){Console.WriteLine(depth);}staticvoidMain(string[]args){RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(A,B,null);如果你想抓住它,将它加载到另一个进程(通过远程回调到你的进程)并让恶意代码在那里执行。另一个进程可能会终止,并且您可以在您身边的管道末端弹出一个整洁的SOE-没有相当不方便的异常的缺点。请注意,同一进程中的单独AppDomain不会将其删除。如果你想从异常中获取堆栈跟踪,下面的代码将对你很好:classProgram{staticvoidMain(string[]args){try{Recurse(0);}catch(Exceptionex){StackTracest=newStackTrace(ex);//去野外。安慰。WriteLine(st.FrameCount);}安慰。读线();}staticvoidRecurse(intcounter){if(counter>=100)thrownewException();递归(++计数器);关于您的编辑,我认为抛出StackOverflowException的用户代码与抛出它的CLR不同。这里有一些关于它的讨论。Jeffrey(Richter,AppliedMicrosoft?.NE??TFrameworkProgramming的作者)的评论适用于实际的堆栈溢出,即如果您的代码包含无限递归,则可能发生堆栈溢出,例如:voidMyMethod(){MyMethod();如果你抛出一个StackOverflowException将像任何其他异常一样处理,并且Jeffrey的评论不适用。此外,Jeffrey的评论说:“如果堆栈溢出发生在CLR本身......”。因此,如果.NETVM可以“干净地”检测到堆栈溢出,即没有将ITSELF运行到堆栈溢出中,那么您应该得到StackOverflowException并且您的catch和finally块应该照常执行。然而,在VMITSELF遇到堆栈溢出的悲惨情况下,你不会那么幸运:VM不会传播StackOverflowException(但会以其他一些奇怪的方式崩溃)并且你的catch和finally块将不会执行.士气是:小心无限递归,因为你不能100%保证VM会干净地检测到它并发出信号!布鲁诺。由于OP引用了这本书,因此澄清了“Jeffrey”是谁。根据MSDN:在.NETFramework的早期版本中,您的应用程序可能会捕获StackOverflowException对象(例如从无限递归中恢复)。但是,目前不鼓励这种做法,因为需要大量的额外代码才能可靠地捕获堆栈溢出异常并继续执行程序。从.NETFramework2.0版开始,try-catch块无法捕获StackOverflowException对象,默认情况下会终止相应的进程。因此,建议用户编写代码来检测和防止堆栈溢出。例如,如果您的应用程序依赖于递归,请使用计数器或状态条件来终止递归循环。请注意,托管公共语言运行时(CLR)的应用程序可以指定CLR卸载发生堆栈溢出异常的应用程序域,并让相应的进程继续执行。有关详细信息,请参阅ICLRPolicyManager接口和托管公共语言运行时。由于这个事实,我不相信你能做你想做的事,因为`StackOverflowException会终止进程。从.NETFramework2.0版本开始,try-catch块无法捕获StackOverflowException对象,相应的进程会默认终止。以上是C#学习教程:为什么ExecuteCodeWithGuaranteedCleanup不起作用?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: