我应该忽略WCF中的第一次机会异常吗?

4
在Visual Studio中运行WCF服务时,我看到Debug输出中出现了大量异常信息。
A first chance exception of type 'System.ServiceModel.FaultException' occurred in System.ServiceModel.dll
A first chance exception of type 'System.InvalidOperationException' occurred in System.ServiceModel.Channels.dll

它们似乎不规则地被抛出:无论如何,我都没有能够找出任何模式(即从每几秒钟到几十秒)。

如果我将调试设置为在FaultException上断点,我会看到它们是由System.ServiceModel.Dispatcher.ErrorBehavior.ThrowAndCatch(Exception e, Message message)抛出的。

异常消息是{"The message with To '' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree."}

显而易见的答案似乎是“你的地址为空”。但这发生在任何客户端连接之前。

这只是“正常”的还是我做错了什么的症状?


只是想澄清一下,你的项目是一个WCF服务,对吗?你是如何连接并调用其中的方法的?是在同一个解决方案中的另一个项目吗?还是使用WCFTestClient.exe? - Boluc Papuccuoglu
@BolucPapuccuoglu,就是这个问题,现在我还没有连接上它... - Benjol
我已经使用WCF多年了,但我没有看到你提到的那些特定的first-chance异常。然而,我经常看到各种其他异常,因为WCF在内部处理它们,它们只是调试器中的额外噪音,并且对我来说不提供任何有用的诊断信息。 - Chris O
3个回答

4
快速答案是:“是的,您可以忽略第一次机会异常”。它们是已经被处理过的异常。因此,它们应该被视为正常的执行流程。
Visual Studio 会在每个异常发生时通知开发人员,即使它已经被处理过了。每个异常都会抛出一个“第一次机会异常”,这不会中断正常的调试会话。如果这个第一次机会异常没有被处理,则调试会话会被“第二次机会异常”中断。 “第一次机会异常”的价值仅供开发人员参考。
在这篇博客文章中,您可以看到更多关于第一次机会异常的详细信息。引用自参考文章:
“第一次机会异常是否意味着我的代码有问题? 大多数情况下,第一次机会异常消息并不意味着代码有问题。对于优雅地处理异常的应用程序/组件,第一次机会异常消息让开发人员知道遇到了异常情况,并已处理。”
希望我能帮到您!

1
异常的类型(即原因)肯定很重要吧?楼主的情况看起来不像是应该“自然发生”的。难道框架在这里只是吞噬异常,这是常说的用户代码绝不能做的事情吗? - Tom W
1
.NET框架是由像我们这样的程序员编写的代码。他们处理异常的方式与我们相同。Visual Studio会在第一时间通知开发人员异常,无论它们被处理在哪个代码部分。因此,虽然您关于不过度使用异常是正确的,但这并不意味着优雅地处理异常是错误的。 - Pantelis Natsiavas
1
我的意思是,在OP所描述的情况下,如果我看到框架经常抛出和处理那种异常,我会感到担忧。在正常使用中,这似乎不是合适的事情。我意识到我正在偏离原始问题并推测WCF组件的设计,所以这可能是在其他地方进行的对话。 - Tom W
@ChrisO:因此,应忽略来自框架程序集的第一次机会异常。另外,应修复吞噬异常的用户编写代码,并严厉惩罚其开发人员。在那时,应完全忽略第一次机会异常。 - John Saunders
@JohnSaunders,那你的答案在哪里,这样我就可以点赞了? :) 我的经验(虽然有限,否则我就不会问这个问题了)是,我依赖的代码中的第一次机会异常有时可能意味着我使用它的方式不正确。我至少想知道为什么。我猜在这种情况下,我只能去Reflector里看看了 :( - Benjol
显示剩余4条评论

0
通常情况下,如果在调试窗口中看到“第一次机会”异常,但如果它们不会崩溃,比如在没有附加调试器的情况下运行w3wp.exe进程,则可以非常确定框架或生成的类正在捕获并处理异常。但是,如果有大量此类消息或怀疑不应抛出任何异常(即使已处理),则可以使用Visual Studio的异常设置来在处理错误时中断以进行调试/跟踪。

0

我认为从框架抛出的所有第一次机会异常都可以安全地忽略,但我们发现如果一个异常被吞掉(而没有“处理”),在生产代码库上捕获隐藏/非常难以复制的错误对我们有用。为FirstChance异常附加一个处理程序,它记录到单独的日志文件并仅在QA环境中启用(这些日志非常大)帮助我们在自己的代码库中发现了几个bug。开发人员在一天结束时查看日志文件,以确定是否有任何不能安全忽略的内容。

尽管这种类型的bug本应该从一开始就不存在于代码中,如果没有人决定吞噬异常,在混乱的真实世界中,这是一个不断提高代码质量的绝佳工具。


最佳实践是不要吞咽异常。 - John Saunders
我完全同意你的看法,John,就像我之前提到的一样。然而,我们经常发现自己在支持一个已经吞噬了异常的大型代码库。这可能是开发人员的无知,或者异常被吞噬在调用堆栈更高的某个位置。 - Rahul Misra
即将进行完整回归测试吗?ReSharper有一个功能,应该使您能够在所有异常被吞噬的地方放置日志记录。当然,接下来您需要对它们进行测试。 - John Saunders
我相信定期查看FirstChance异常是一个有用的工具,如果开发人员有几个小时的时间来分析日志。这对于被认为在生产环境中运行良好的遗留代码尤其相关。在一个庞大的应用程序中有成千上万的类,QA在紧张的预算下不可能执行每个可能的测试场景。这不是最佳实践和QA测试的替代品,而是一种额外的工具,以主动改进代码库。 - Rahul Misra
好的,但那不是我所暗示的。我的意思是,“结构化搜索和替换”可以以安全的方式应用于大型代码库。当然,您需要测试任何更改过的代码。 - John Saunders

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