WCF服务最佳实践,以保持我的服务活力

时间:2013-05-23 13:16:43

标签: c# wcf servicehost

我的WPF应用程序中有几个WCF服务,我使用这种方法打开它们:

private void StartSpecificWCFService(IService service, string url, Type serviceInterfaceType)
{
    ServiceHost serviceHost = new ServiceHost(service, address);
    serviceHost.AddServiceEndpoint(serviceInterfaceType, new NetNamedPipeBinding(), url);
    serviceHost.Open();
    //sign to serviceHost.Faulted ??
    _wcfServicesHolder.Add(serviceHost); //A dictionary containing all my services
}

服务属性是:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]

服务是日志服务和事件服务,它们从其他进程获得许多调用。我使用namedpipes,因为它是最快的,并且进程在SAME计算机上运行。

我的问题是 - 我如何保持这些服务一直在上升?

  1. 轮询计时器,迭代_wcfServicesHolder并检查服务是否已打开
  2. 签署serviceHost.Faulted事件。
  3. 在服务处于故障状态后,是否必须重新创建客户端(在不同的进程上)?或者它仍然可以在同一频道上播放消息?

    我收到的例外是:

    There was no endpoint listening at net.pipe://localhost/LoggingService that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details
    

2 个答案:

答案 0 :(得分:1)

为什么服务具有InstanceContextMode = InstanceContextMode.Single并发线程访问权限?服务是否具有某种内存中线程安全状态?如果没有,那么尝试重新考虑使用InstanceContextMode.PerCall的服务可能是值得的。在配置WCF服务时,这应该是您的默认选择 - WCF主要是用于实现面向服务的体系结构的技术,并且使用PerCall以外的模式违反了SO Design Principles的无状态原则。

为了支持这一点,如果你有InstanceContextMode.Single的服务器端错误,这表明服务中出现了严重错误。您在服务中维护的任何状态都将丢失 - 客户不能指望重新连接并恢复正常。

无论您最终使用的InstanceContextMode是什么,如果您的频道在一段时间内没有客户端与其连接,您的频道就会出现故障。通过TCP(或任何明确公开可靠会话的协议),您可以在可靠会话上指定不活动超时,但您没有使用管道的此类选项。

使用管道,使通道打开的时间超过配置的超时时间,将使通道出现故障,使其无效。如果您有兴趣在应用程序的生命周期内保持对服务开放的通道,则可以订阅通道故障事件,并重新创建代理。正如你所建议的那样 - 另一个选择是继续沿着频道进行轮询以使其保持活力。

答案 1 :(得分:1)

为了保持您的服务主机,请使用您的#2选项(订阅服务主机上的故障事件)。出现故障时,您需要中止servicehost,新建一个新实例,重新连接故障事件处理程序,然后打开服务主机。

关于这种情况的官方文档并不多,但这是一篇来自msdn博客的旧帖子,描述了你正在寻找的东西。

http://blogs.msdn.com/b/drnick/archive/2007/01/16/restarting-a-failed-service.aspx

对于客户端,当所述频道出现故障时,还需要重新建立到服务器的频道。

相关问题