16

我们在 WCF 应用程序中使用了一个发布-订阅模型,该模型几乎遵循 Microsoft 示例:设计模式:基于列表的发布-订阅

虽然服务提供了subscribe()和的概念,unsubscribe()但在客户端死亡或通道故障的情况下处理清理的最佳实践是什么?目前,当客户端订阅时,我将处理程序附加到当前InstanceContextClosedFaulted事件(服务用户使用 PerSession 实例上下文模式和 netTcpBinding):

_communicationObject = OperationContext.Current.InstanceContext;
_communicationObject.Closed += OnClientLost;
_communicationObject.Faulted += OnClientLost;

OnClientLost处理程序只是取消订阅客户端,但是:

  1. 上面的做法是否是一个好的做法,并且足够强大,可以在客户端断开双工通信时捕获所有情况?或者服务是否应该只处理在尝试与客户端通信并处理清理时遇到的异常?
  2. 除了取消订阅客户端回调处理程序之外,是否应该执行任何进一步的清理,尤其是在出现故障的情况下?

这个问题提出了一个类似的问题,但最终没有提供对客户端调用订阅和/或取消订阅之外的案例的答案

谢谢

4

2 回答 2

8

我做了一些测试,将处理程序附加到回调通道的 Closed 和 Faulted 事件,然后在服务器调用回调之前杀死客户端。在每次试验中,Closed/Faulted 事件会在服务器尝试调用回调之前立即触发。尽管如此,我仍然将回调调用包装在 try-catch 块中,因为客户端通道的破坏可能会在另一个线程进入回调时发生。

唯一需要的清理工作是删除对回调通道的引用。WCF 和垃圾收集器完成其余的工作。

于 2011-01-20T16:28:06.727 回答
2

处理这些事件将使您的订阅者列表保持同步。它确实足够强大。请记住,如果客户端在消息传输过程中掉线,您可能会在这些事件触发之前收到异常,因此请准备好忽略它们以便清理事件。

除了从订阅者列表中删除客户端外,其他清理完全取决于您的应用程序(即释放您在客户端连接时获得的资源)。我不知道需要进行任何其他清理。

于 2011-01-13T22:17:47.307 回答