我在我的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)]
这些服务包括日志服务和事件服务,它们从其他进程得到许多调用。我使用名称管道,因为它是最快的,进程在同一台计算机上运行。
我的问题是-我如何维持这些服务的所有时间?
在服务处于故障状态之后,是否必须重新创建客户机(处于不同进程)?还是仍然可以在同一个频道上播放信息?
我收到的例外是:
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
发布于 2013-05-24 16:22:04
为什么服务具有并发线程访问的InstanceContextMode = InstanceContextMode.Single
?这些服务是否保持某种内存线程安全状态?如果不是,那么尝试重新考虑使用InstanceContextMode.PerCall
的服务可能是很值得的。在配置WCF服务时,这应该是您的默认和首选选择-- WCF主要是一种用于实现面向服务的体系结构的技术,并且使用PerCall
以外的模式违反了所以设计原则的无状态原则。
为了支持这一点,如果InstanceContextMode.Single
存在服务器端错误,这表明服务中出现了严重错误。您在服务中维护的任何状态都将丢失--客户端不能期望只重新连接并恢复正常。
不管您最后使用的是什么InstanceContextMode
,如果您的通道在一段时间内没有客户端连接,那么它就会出现故障。在TCP (或任何显式公开可靠会话的协议)上,您可以在可靠会话上指定非活动超时,但没有使用管道的此类选项。
使用管道,使通道打开的时间比所配置的超时时间长,这将使通道失效。您可以订阅通道故障事件,如果您有兴趣在应用程序的生存期内保持对服务开放的通道,则可以重新创建代理。正如您所建议的,另一种选择是沿着通道保持轮询,以保持它的活力。
发布于 2013-05-24 16:43:06
为了保持服务主机正常运行,可以选择#2 (订阅服务主机上的错误事件)。当发生故障时,您需要中止servicehost,新建一个新实例,重新连接故障事件处理程序,并打开服务主机。
关于这个场景,官方文档不多,但这里有一篇来自msdn博客的旧文章,描述了您要寻找的内容。
http://blogs.msdn.com/b/drnick/archive/2007/01/16/restarting-a-failed-service.aspx
对于客户端,当所述通道发生故障时,它还需要重新创建到服务器的通道。
https://stackoverflow.com/questions/16714966
复制相似问题