3

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

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

和命名管道?

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

4

3 回答 3

11

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

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

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

于 2011-02-28T17:50:15.607 回答
7

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

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

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

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

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

于 2011-02-28T18:37:30.770 回答
0

这就是 WCF 所做的:

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

这里'SomeOp'失败了,而不是'a',那么为什么SomeOtherOp必须失败呢?

这是有道理的,如果

Proxy a = new Proxy(); -> threw exception
a.SomeOp() -> faulted
于 2012-07-25T20:33:14.210 回答