WCF 通道故障状态是不是有帮助?

Posted

技术标签:

【中文标题】WCF 通道故障状态是不是有帮助?【英文标题】:Does WCF Channel Faulted state help at all?WCF 通道故障状态是否有帮助? 【发布时间】:2011-07-05 22:45:38 【问题描述】:

我无法将故障通道的概念映射回某些绑定的手动实现。我认为这个 WCF 功能很烦人,我想知道是否有任何方法可以禁用它。

以 TCP 为例。大多数 TCP 通信都断开了。那么到底为什么一个连接会导致通道故障并断开所有后续连接呢?

还有命名管道?

也许我错了。所以请解释为什么它是一个特性,而不是一个错误。

【问题讨论】:

【参考方案1】:

我认为它是 Juval Löwy(WCF 架构师之一)WCF 整体理念的产物。引用他的书Programming WCF Services

这个[异常系统和正常的使用方式]是.NET作为一个平台的一个根本缺陷。 [...] 这里 [在抛出异常之后],发生了一些完全出乎意料和可怕的事情。客户怎么可能假装不这样呢?该对象可能已被彻底破坏,但客户端仍在使用它。

这个想法是,毕竟,您正在与您正在使用的任何传输通道的另一端的 object 进行通信,并且如果该对象抛出异常,它可能无法使用任何更多的。这是一个有趣的观点,但我不确定我是否完全同意(因为正如你所说,这在实践中可能会很烦人)。

【讨论】:

+1 正如 Juval 喜欢说的:你的服务被炸毁了 - 到处都是血液和身体部位;你还想再次调用它吗? - 没有比这更多的图形了 :-)【参考方案2】:

FaultedCommunicationObject 状态机的状态之一,它被嵌入到许多 WCF 抽象的实现中。它本质上意味着该对象的“游戏结束”,因此您不会找到任何方法来禁用它。

这当然不是错误:所有这些人工制品背后的CommunicationObject 状态机是有意识的设计选择。虽然讨论 WCF 架构师做出的设计决策可能会引起人们的兴趣,但如果您想使用 WCF,最终您只需要接受事情的现状并继续前进。

您应该认为通道不仅仅是正在使用的传输的适配器:它是一个更高级别的抽象,它封装了通信堆栈中的许多不同层(传输、编码、安全、会话管理、交易流、双工等)。

即使查看特定绑定的详细信息,您也会发现堆栈中很少有元素具有容错性,以至于您可以在先前的通信尝试失败后安全地重用它们(例如 HTTP 协议,也许)。即使您提到的那些(TCP,命名管道)也没有您建议的那样容错。

我认为CommunicationObject 状态机或类似的东西或多或少是必不可少的,以便拥有一个比其所有组成层/元素的基本细节更高级别的通道抽象。它启用了简单的规则:如果是Faulted,则将其扔掉并制作一个新的。是的,在某些情况下,您可能会错过通过保留一些可以安全重用的资源来实现的优化;但这是您使用更简单的通信抽象所付出的(小)成本。

【讨论】:

【参考方案3】:

这就是 WCF 的作用:

Proxy a = new Proxy();
a.SomeOp() -> threw exception
a.SomeOtherOp() -> faulted

这里是“SomeOp”失败,而不是“a”,那么为什么 SomeOtherOp 必须失败?

如果

Proxy a = new Proxy(); -> threw exception
a.SomeOp() -> faulted

【讨论】:

以上是关于WCF 通道故障状态是不是有帮助?的主要内容,如果未能解决你的问题,请参考以下文章

为啥缓存 WCF 通道是一件坏事?

保持 wcf 回调通道无限期打开/如果出现故障则从客户端重新连接

通过共享通道并发 WCF 调用

WCF:是不是可以在双工通道中使用流模式?

Wcf 回调网络 tcp 双工仅 1 路故障

使用通道工厂而不是使用代理或添加服务引用来使用外部 WCF 服务