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

什么可以导致重置一个callstack(我正在使用“throw”,而不是“throw ex”)分享

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

C#学习教程:什么会导致调用堆栈重置(我使用的是“throw”,而不是“throwex”)")")我一直认为“抛出”和“抛出ex”之间的区别在于单独抛出并没有重置异常的堆栈跟踪。不幸的是,这不是我遇到的行为;这是一个简单的示例,它重现了我的问题:使用System;使用System.Text;命名空间testthrow2{classProgram{staticvoidMain(string[]args){try{try{thrownewException("line14");}catch(Exception){throw;//第18行}}catch(Exceptionex){Console.WriteLine(ex.ToString());}Console.ReadLine();}}我希望这段代码打印从第14行开始的调用堆栈;然而,调用堆栈从第18.当然,这在示例中没什么大不了的,但在我的实际应用程序中,丢失初始错误消息是一种痛苦。我是否遗漏了一些明显的东西?是否有任何其他方法可以实现我想要的(即重新抛出异常而不会丢失堆栈信息?)我正在使用.NET3.5你应该阅读这篇文章:简而言之,throw最初抛出的异常的堆栈跟踪通常被保留,但前提是当前堆栈帧中没有发生异常(IE。方法)。您使用的方法PreserveStackTrace(在博文中显示)保留原始堆栈跟踪,如下所示:try{}catch(Exceptionex){PreserveStackTrace(ex);扔;但我通常的解决方案是要么不捕获并重新抛出这样的异常(除非绝对必要),要么总是使用InnerException属性抛出一个新的InnerException来传播原始异常:try{}catch(Exceptionex){thrownewException("执行foo时出错",ex);}问题是Windows正在重置堆栈的开始。CLR的行为符合预期——这只是主机操作系统异常处理支持的一个限制。问题是每个方法调用只能有一个堆栈帧。您可以将异常处理例程提取到一个单独的“帮助程序”方法中,这将解决WindowsSEH强加的限制,但我认为这不一定是个好主意。在不丢失堆栈信息的情况下重新抛出异常的正确方法是抛出一个新的异常并将原来捕获的异常包装为内部异常。很难想象您实际需要执行此操作的许多情况。如果您不处理异常,只是捕获它以重新抛出它,您可能一开始就不应该捕获它。正常的重新抛出会保留堆栈跟踪中的所有内容,但如果当前方法在堆栈跟踪中,则行号将被覆盖。这是令人讨厌的行为。在C#中,如果你需要在特殊情况下做一些事情但不关心异常是什么,你可以使用这个模式:Booleanok=False;试试{做点什么();好的=真;}finally{if(!ok)//异常发生!handle_exception();这种模式在一些数字中非常有用;最常见的是应该返回一个新的IDisposable的函数。如果函数不返回,则必须清理一次性对象。请注意,上述“try”块中的任何“return”语句都必须将ok设置为true。在vb.net中,您可以在函数上使用稍微好一点的模式,尽管代码中的一点有点恶心,使用以下模式:DimPendingExceptionAsException=Nothing;尝试做一些PendingException=Nothing'看到CopyFirstParameterToSecondAndReturnFalse(Ex,PendingException)中的评论当捕获ExExceptionthrow'将永远不会被执行,因为上面将返回一个错误最后如果PendingExceptionIsNotNothing那么..处理异常以防它结束尝试长命名函数应该以明显的方式实现。这种模式的优点是它使代码可用。虽然这在只处理但不捕获的情况下通常不需要,但在一种情况下它可能是无价的:如果清理例程抛出异常。通常,如果清理例程抛出异常,则所有挂起的异常都会丢失。但是,使用上述模式,可以将挂起的异常包装在清理异常中。上面代码有一个有趣的注意事项:异常可以到达“CatchWhen”,但Try语句可以正常完成。不清楚在这种情况下会发生什么,但很明显,终止语句不应显示为好像有待处理的异常。清除PendingException将使它如此,如果异常消失,代码将表现得好像它从未发生过一样。另一种方法是包装并重新抛出已知发生的异常,因为这种情况几乎肯定表明内部异常处理代码存在问题。以上就是C#学习教程分享的:Whatcancauseacallstacktobereset(我用的是“throw”,不是“throwex”),如果对大家有用,需要详细了解C#学习教程,希望请注意——本文摘自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: