托管在 Windows 服务中的 WCF 服务 - 应该由哪一个来完成所有工作?

Posted

技术标签:

【中文标题】托管在 Windows 服务中的 WCF 服务 - 应该由哪一个来完成所有工作?【英文标题】:WCF Service hosted in a Windows Service - Which one should do all the work? 【发布时间】:2016-06-17 22:23:39 【问题描述】:

我正在编写我的第一个 WCF 服务,但我有点不确定应该在哪里实现服务的主要功能。

我的服务的主要目的是按计划执行任务并最终将其状态记录回远程服务器。 WCF 服务的理念是允许系统托盘应用程序和服务之间进行通信。我的问题是我应该在哪里实现任务调度和数据库日志记录?

应该: A) Windows 服务只承载 WCF 服务,不做任何其他事情,让 WCF 服务完成所有工作和通信。

B) Windows 服务托管 WCF 服务并完成所有工作,让 WCF 服务进行通信而不是其他任何事情。

在 B 的情况下,Windows 服务如何从 WCF 服务获取数据? ServiceHost 似乎不提供对 WCF 服务方法的访问。那么我是否需要像在系统托盘应用程序中一样创建一个新的客户端实例并连接到 WCF 服务?是否可以同时连接多个? (我使用的是net.tcp,主要是因为我遵循的教程正在使用它。)还有一种可能是我可能希望服务器应用程序稍后连接到客户端的WCF服务。

【问题讨论】:

【参考方案1】:

服务不像程序那样具有“主要功能”——它提供了一个服务合同(接口),其中包含可由服务客户端调用的操作。 WCF 允许将该合约暴露给可能在不同进程或不同机器上运行的调用者。

一旦您实现了 WCF 服务,您就可以通过多种不同的方式来托管它。一种方法是在 Windows 服务进程中。为此,您通常会创建一个 System.ServiceModel.ServiceHost 包含您的服务类型(或实例)和 Open() 它。

Windows 服务在初始创建之后不会与 WCF 服务实例通信 - 服务主机将处理对地址和绑定指定的端点的任何调用,并将它们分派到您的服务实例。

因此,您的“A”选项最接近您想要的。

您的托盘应用程序将成为服务客户端,并将通过向服务(其 ServiceHost 将监听它们)发送消息来调用操作。

要同时处理多个操作,您需要熟悉System.ServiceModel.ConcurrencyMode。

请注意,在您的场景中,如果您不希望从另一台机器调用服务,您可能需要考虑使用named pipe binding 而不是 TCP 绑定。

【讨论】:

同意,我认为选项 A 听起来最好,因为最终 Windows 服务可能是您想要为最终用户包装体验的内容,但将来可能不会(与一个 WCF 服务,它是一个更通用的包装器)。这样想。如果您想添加对 Linux 的支持或适应 Windows 操作系统的变化,那么您会很高兴最大限度地减少对 Windows 的依赖。对 WCF 的依赖是两个弊端中较小的一个。我怀疑这至少会持续几十年(作为一种哲学)。 谢谢。我知道没有像控制台应用程序中那样的“主要”功能/入口点。但是基于选项 A,正如你们都建议的那样,我的计划是使用“Public Sub New”来启动计时器,该计时器将等待预定时间并触发自定义功能来执行所需的任务。你说这可行吗?目前我不确定,但我可能会在某个时候从远程机器调用函数以允许服务器更新预定时间。但否则我会看看命名管道谢谢。我一定会研究并发模式。

以上是关于托管在 Windows 服务中的 WCF 服务 - 应该由哪一个来完成所有工作?的主要内容,如果未能解决你的问题,请参考以下文章

托管在 Windows 服务中的 WCF 服务在停止时挂起

如何在虚拟机中使用托管在 Windows 服务中的 WCF

Azure 功能无法访问托管在内部 windows 服务器中的 WCF 服务

托管在 Windows 服务中的 WCF 服务 - 应该由哪一个来完成所有工作?

域服务器和域外客户端中的 net.tcp wcf 服务(托管 Windows 服务)

Windows 服务(托管 WCF 服务)在启动时立即停止