如何处理低级别WCF错误?

如何处理低级别WCF错误?,wcf,Wcf,我的服务中有标准错误处理: 我有一个IErrorHandler连接到服务以处理服务执行期间的意外错误 我在所有的服务方法中都有try/catch块来处理预期的情况 但是,在某些情况下,会在服务器上引发异常,并且两个异常都不会被调用 以下是服务器异常未发送到IErrorHandler的情况: 将服务器绑定上的ReceiveTimeout设置为5秒 在客户端上,执行以下操作: 在这种情况下,错误会在服务器上抛出,但我找不到处理它(并记录它)的方法。我知道会引发错误,因为如果我在服务器进程上

我的服务中有标准错误处理:

  • 我有一个IErrorHandler连接到服务以处理服务执行期间的意外错误
  • 我在所有的服务方法中都有try/catch块来处理预期的情况
但是,在某些情况下,会在服务器上引发异常,并且两个异常都不会被调用

以下是服务器异常未发送到IErrorHandler的情况:

  • 将服务器绑定上的ReceiveTimeout设置为5秒

  • 在客户端上,执行以下操作:

在这种情况下,错误会在服务器上抛出,但我找不到处理它(并记录它)的方法。我知道会引发错误,因为如果我在服务器进程上附加了调试器并在所有异常上中断,调试器将中断

我还发现了其他类似的情况,其中低级错误没有传递给我的程序

在哪里可以挂接代码,以确保在将服务器上发生的所有异常返回到客户端应用程序之前,我可以处理这些异常?我应该实现自己的IChannel还是其他一些低级接口

谢谢


2009年9月21日更新:参见Microsoft WCF论坛上的帖子。如果我想处理这种类型的异常,我可能必须实现自己的通道。当我有更多信息时,我会再次更新这篇文章。

重点是-如果服务器无法访问或无法处理消息,服务器上不会出现错误-错误将在客户端弹出(“TimeoutException”或其他)

因此,在这些情况下,在服务器上安装IErrorHandler真的没有什么帮助,因为错误确实发生在客户端(由于网络关闭、服务器地址或sstuff之类的输入错误,无法建立连接)

因此,在客户端,您肯定还必须使用try…捕获所有服务器调用


Marc

设置诊断跟踪,并使用检查日志。链接还包含有关配置跟踪的信息。

使用FaultContracts。然后可以在客户端处理故障

这对于调试来说也更好,因为通常您在开发客户机时,不希望为了调试目的而关闭服务器

在客户端,使用try/catch块捕获所有异常/错误。服务器端肯定存在无法检测到的错误,例如通信问题,因此您需要在客户端处理错误


如果需要集中的错误处理,可以创建一个服务,该服务接收有关所有错误的消息,将错误发送到该服务器,并让它记录该错误。如果您想要创建一个集中的消息跟踪/性能分析/日志记录工具,并拥有大量的应用程序处理器、服务器、客户端等,这将非常有用。

经过大量的研究和实验,答案是:

此时(.Net 3.5)没有任何机制允许处理WCF调用上下文中可能发生的所有异常

服务方法执行期间发生的异常可以通过以下方式轻松处理:

  • 在所有服务方法中尝试/捕获块以处理预期情况
  • IErrorHandler连接到服务以处理服务执行期间的意外错误
  • 但是,对于低级别的WCF基础结构错误,没有完美的解决方案。现有的最佳解决方案似乎是实现自定义通道以捕获更多异常

    在中,Microsoft确认无法处理所有类型的WCF基础结构错误


    在中,有一个关于如何实现自定义通道的示例。该解决方案仅适用于HTTP,不适用于HTTPS。此外,某些WCF基础结构错误也不会被自定义通道捕获(请参阅该特定线程中的更多详细信息)。

    此处不应使用receiveTimeout服务器绑定-只有在调用GetData()时,才会使用超过5秒的时间接收响应。你的客户睡眠10秒没有效果。假设初始测试服务没有重现问题,并且正在更新服务器绑定以将receiveTimeout设置为5秒。您接收到客户的错误是什么?实际上,我会怀疑服务器绑定/行为配置错误,尤其是在代码中没有中断服务的情况下。在客户端/服务上启用WCF调试并查看它显示的内容。如MSDN中所述,server receiveTimeout是服务器等待空闲开放通道的最长时间。在这种情况下,超过了时间量。客户端上的异常是具有内部FautException的MessageSecurityException。内部FaultException表示已超过receiveTimeout.Interest。我想这也可能是一个线索,说明为什么它在第一次通话中有效,而不是在第二次通话中有效。您能否在接收超时时转发指向您参考的文档的链接?恐怕我对这个价值的理解有缺陷。我指的文件是,谢谢!这是医生:。@Zach:我并不为第二个电话不起作用而感到困惑。这是我所期望的。让我困惑的是,我似乎找不到在服务器上得到通知的方法。最后,我的客户端应用程序比我更了解服务器上发生的错误。不正确。是服务器拒绝处理呼叫,因为receiveTimeout已过期。因此,服务器会引发异常。正如我写的,我可以在服务器进程上附加调试器,然后我看到异常被引发;问题是,在返回到客户端之前,它没有传递给处理程序。我需要一种在服务器上处理此异常的方法。好的,您的receiveTImeout是正确的-但是当客户端尝试连接时,可能会发生其他错误(特别是通信错误),并且永远无法到达服务器,在这种情况下,服务器上的IErrorHandler
    Service1Client sc = new Service1Client();
    ICommunicationObject o = sc as ICommunicationObject;
    
    o.Open(); // open channel
    
    sc.GetData(10); // do a first call
    
    Thread.Sleep(10000); // wait longer than the server receiveTimeout
    
    sc.GetData(10); // Attempt another call: server throws a FaulException