C#实时异常捕获

7

我希望得到一位真正使用C#进行实时编程或真正了解语言内部的人的回复。

我知道异常不应该用于处理正常处理,而只能用于检测错误条件。这个话题已经有很多讨论了。

我想知道仅仅在一个try/catch块中(除非程序必须结束,否则永远不会捕获异常)是否会导致运行时减速。try/catch块位于必须重复调用的函数内部。我怀疑成本只有极小的代价。

这个成本可以用CPU周期、其他任务(与浮点乘法的成本相同)或其他方式来量化吗?

我们使用Microsoft C#.Net 3.5在Windows XP下。


1
请查看Jon Skeet关于异常和性能的资源:http://www.yoda.arachsys.com/csharp/exceptions.html - Robert Venables
2个回答

11

.NET异常的开销非常低,除非它们被抛出。使用try/catch块对性能影响极小,即使在非常快速、紧密的循环中也几乎没有影响。

然而,在.NET中,一旦抛出异常,它们就会变得非常昂贵。与许多其他语言相比,如果您抛出异常,则对性能的影响可能更大。这是由于创建异常时获取的完整堆栈信息等原因。

这与其他一些语言(如Python)的行为相反,其中异常处理具有较高的成本,但抛出异常实际上相当高效。

但是,如果您担心性能问题,建议通过分析来测试您的程序。在进行了相当多的性能分析后,这是我的经验。在您自己的代码库中测量才是最好的方法。


实际上,只有在访问StackTrace属性时,或者异常通过进程边界(即远程/WCF等)时才会发生堆栈跟踪。创建异常也非常低成本,因为构造只设置了少数几个属性。通过抛出过程设置StackCrawlMarks会产生中等成本,这有助于进行堆栈爬行,如果请求了StackTrace,则会发生...但在.NET 2.0中,除非您实际访问它,否则不会在每个抛出时发生跟踪。 - jrista
是的 - 我实际上是在指堆栈标记机制,但我的回答不够清晰。然而,在我的性能分析中,这确实有相当大的开销(假设是关键性能系统)。Rico Mariani有一篇很好的博客文章解释了原因,但对我来说,问题在于额外的缓存未命中和页面故障:http://blogs.msdn.com/ricom/archive/2006/09/25/771142.aspx - Reed Copsey
感谢提供这个信息。不幸的是,我们没有工具来分析我们的代码... 我们只能遵循最佳实践。 - Mark T
2
如果你正在编写实时软件,你需要使用性能分析器。没有什么比测量更重要了。你可以遵循所有规则编写代码,但你认为会有良好性能的部分可能成为瓶颈——这种情况经常发生。.NET有许多性能分析器可供选择,包括一些免费的工具。 - Reed Copsey

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接