1

我的 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)]

这些服务是日志服务和事件服务,它们从其他进程收到许多调用。我使用命名管道,因为它是最快的并且进程在同一台计算机上运行。

我的问题是 - 我如何保持这些服务一直处于运行状态?

  1. 轮询计时器,迭代 _wcfServicesHolder 并检查服务是否已打开
  2. 登录 serviceHost.Faulted 事件。

并且在服务处于故障状态后,是否必须重新创建客户端(在不同的进程上)?或者它仍然可以在同一频道上广播消息?

我收到的例外是:

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
4

2 回答 2

1

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

关于这种情况的官方文档并不多,但这里有一篇来自 msdn 博客的旧帖子,描述了您正在寻找的内容。

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

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

于 2013-05-24T16:43:06.253 回答
1

为什么服务具有InstanceContextMode = InstanceContextMode.Single并发线程访问?服务是否保持某种内存线程安全状态?如果不是,那么尝试重新考虑要使用的服务可能是值得的InstanceContextMode.PerCall。这应该是您配置 WCF 服务时的默认和首选选择 - WCF 主要是一种用于实现面向服务的架构的技术,并且使用的模式不是PerCall违反SO 设计原则的无状态原则。

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

无论InstanceContextMode您最终使用什么,如果在一定时间内没有客户端连接到它,您的通道将保持打开状态。通过 TCP(或任何显式公开可靠会话的协议),您可以在可靠会话上指定不活动超时,但使用管道没有这样的选项。

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

于 2013-05-24T16:22:04.077 回答