Windows服务通过wcf连接到其他服务崩溃

时间:2011-03-25 12:02:32

标签: wcf windows-services

我有两个Windows服务。一个(“服务器”)充当另一个(“客户端”)连接的WCF主机。所以我已经配置了从客户端服务器的依赖项。两者都设置为自动启动。

当我手动启动这些服务时,一切正常。当我停止两个服务并告诉客户端启动时,服务器将在客户端之前启动,一切正常。

但是,当我重启机器时,只启动服务器

当我添加诊断监听器时,我看到它有一个TimeoutException,其中包含有用的消息:

  

对“http://[server地址”的HTTP请求超过了分配的超时00:00:00。分配给此操作的时间可能是较长超时的一部分。

在其他一些SO问题上,有an answer声称WCF可能会对出现问题感到困惑,因此会对超时开始撒谎。

我是否可能错过任何服务的依赖?当客户端尝试联系服务器时,WCF是否需要尚未启动或正在启动的内容?

2 个答案:

答案 0 :(得分:2)

我认为您应该检查您的客户服务。在启动时,Windows服务正在启动,而网络设备仍在初始化。服务应该准备好在没有网络且没有任何网络设备的情况下启动。通常的方法是保持定期重试以建立连接。您可以通过卸载所有网络适配器并尝试启动服务来对您的计算机进行少量实验。

您可以执行的其他快速解决方法是在服务上设置恢复选项 - 例如,您可以将其配置为在超时后重新启动服务 - 您可以通过services.msc中的UI或命令行中的UI来执行此操作'sc config'命令。

答案 1 :(得分:2)

配置两个Windows服务之间的依赖关系不一定足以避免出现竞争条件:即避免客户端服务在服务器的WCF通道堆栈完全初始化之前调用WCF服务。

服务依赖性只是确保Windows服务控制管理器在服务器Windows服务已通知SCM已启动之前不会启动客户端服务进程。这是否足够取决于您如何编写服务器。

如果服务器服务启动了一个初始化WCF堆栈的新线程,则可能在WCF堆栈为客户端做好准备之前返回OnStart方法。然后是关于客户的第一次通话是否会成功的竞争条件。

另一方面,如果服务器服务没有从OnStart返回(因此没有通知SCM它已经启动),直到通道堆栈完全打开,依赖项将删除竞争条件,但是有一个不同的缺陷:您需要注意,在等待WCF堆栈初始化时,不会触发SCM自身启动Windows服务的超时,例如,如果WCF服务依赖于网络堆栈,则可能会在重新启动时发生。如果服务器的OnStart未在SCM超时内返回,则SCM根本不会尝试启动从属客户端服务,因为它不会收到服务器的启动通知。 (来自SCM的Windows事件日志中将显示一条消息,指出服务器服务未在预期时间内启动。)您可以在初始化WCF服务时通过调用ServiceBase.RequestAdditionalTime来扩展SCM超时。

无论哪种方式,客户端服务确实应该被编写,以便在第一次WCF调用不成功时它不会完全失败。

您实际上并没有说出您正在使用的绑定。如果客户端和服务器服务总是在同一台机器上运行,如您所示,那么请考虑使用NetNamedPipeBinding:那么您的服务将不依赖于网络资源的初始化,启动应该更快。