在我们的 WF4 工作流服务中,我们尝试尽可能健壮。我们要做的一件事是在 HandleError 和 ProvideFault ( IErrorhandler ) 中记录错误。文档明确指出 HandleError 将是进行日志记录的正确位置,但我看到一些奇怪的事情发生了:
System.NullReferenceException:未将对象引用设置为对象的实例。
在 System.ServiceModel.Activities.Dispatcher.DurableInstanceManager.GetInstanceAsyncResult.GetInstance()
在 System.ServiceModel.Activities.Dispatcher.DurableInstanceManager.GetInstanceAsyncResult..ctor
System.ServiceModel.CommunicationException:从管道读取时出错:管道已结束。 (109, 0x6d)。
在 System.ServiceModel.Channels.PipeConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
在 System.ServiceModel.Channels.SessionConnectionReader.Receive(TimeSpan timeout)
所以我的结论是,要记录所有错误,我必须同时登录这两种方法。但这会导致大量重复的日志条目,因为 3..
我当前的解决方法是“记住”上次记录的来自 ProvideFault 的异常,如果相同的异常进入 HandleError,则忽略它。对我来说看起来不是很干净。
有没有更好的,可靠的方法来记录全部 WF 服务中可能发生的错误?
并且请不要指向Logging exceptions in WCF with IErrorHandler inside HandleError or ProvideFault?因为这没有提供任何帮助。
最佳答案
我已经看到场景 2 发生在不同的上下文中(BizTalk 适配器),而且似乎 HandleError
被调用是因为适配器中发生了异常,但是 ProvideFault
是 不是 调用是因为没有实际返回的消息 - 错误发生的方式阻止了适配器实际生成/读取/转换消息并将其传递到管道。这似乎甚至排除了 故障 生成的消息。从管道读取失败似乎构成了这一点 - 您的服务不知道它是否失败,因为它甚至从未连接过,或者是否因为远程服务器失败而失败。诸如 TransactionAbortedException
之类的东西也可能导致这种情况,或者(在我的特殊情况下)SqlException
可以导致它。
这应该为案例 #1 提供一些线索,我自己没有见过或复制它:这是由于消息链中某处的异常处理不当。在这种情况下,生成了一条错误消息,但链上的某些东西无法以 HandleError
的方式处理异常。可以调用。一个 NullReferenceException
在这里是有道理的——如果你没有正确处理空检查,很难说在这种情况下还会发生什么。
就解决这个问题而言,我可能会尝试在两个地方都登录,并提供一些额外的信息来解释日志的来源。这将是故障安全的,即使它确实重复记录。另一方面,如果您有一个生成这些场景中的一个或两个的异常列表,您可以实现逻辑来检查它是什么类型的异常(或它发生的位置) - 如果它是一个异常,则可能会减少日志记录可能会被其他方法处理。
关于wcf - 工作流服务中的HandleError vs. ProvideFault不一致,如何处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17527374/