实施Windows服务 - 如何满足这些要求?

时间:2011-04-15 12:59:58

标签: c# sql-server windows-services

我正在寻找有关实施Windows服务的一般建议。我的要求如下:

  • 服务处理来自数据库的行 - 因此,如果存在具有特定状态的行,则需要执行一些工作,写入其他一些表,然后将该行标记为正在处理。
  • 服务启动时可能有数千行等待处理 - 它应该全部处理它们。
  • 然后服务应继续运行,处理任何行,因为它们写入 ForProcessing 表。
  • 我需要能够优雅地关闭它 - 我不想要任何半处理过的行
  • 它需要高效执行 - 我不想在可能的情况下轮询数据库

所以我的具体问题是:

  • 如何保持活着并在写入新行时对其进行响应?我可以使用某种SQLDependency对象来有效地处理新行吗?
  • 如何处理优雅启动并关闭?
  • 从数据库中提取行时,我应该获取所有等待处理的行,还是一次只获取一行?
  • 据推测,鉴于它已经是后台服务,我会同步处理行?换句话说,没有必要在后台线程上处理行?
  • 在帐户和运行权限方面我需要考虑什么?这是部署问题吗?
  • 还有其他任何需要注意的问题吗?

感谢您的任何建议。

聚苯乙烯。有没有其他合理的替代方法来使用Windows服务来实现这一目标?

2 个答案:

答案 0 :(得分:5)

编写Windows服务并不是那么困难,但最初肯定是令人生畏的。

就清除业务逻辑而言,我通常会首先编写一个命令提示程序,因为它更容易调试 整个

现在,关于服务。当然,使用Visual Studio创建Windows服务项目。

  

如何保持活着并在写入新行时对其进行响应?我可以使用某种SQLDependency对象来有效地处理新行吗?

嗯,我不确定你能否,但我可以告诉你你需要什么。你需要一个线程。如果您未在OnStart事件中创建新线程,您的服务将立即停止。这个线程可以直接使用.NET的许多线程mechinisim创建,也可以通过某种类型的Timer,FileSystemWatcher(可能不适用于你)或者其他人间接创建。

  

如何处理优雅的启动和   关闭?

您可以在OnStop中执行此操作。你可以通过信号通过一个全局变量发信号通知你是时候关闭了。然后,由您的线程及时通知信号并清理并退出线程。如果您处于可能需要20秒以上的事情中间,则需要告诉SCM(服务控制管理器)您需要更多时间。如果你不这样做,那么停止服务的用户就会收到消息说服务没有响应,最终会被杀死。

  

从db中获取行时,我应该获取所有正在等待处理的行,还是一次只取一个?

这是一个商业决定。可能应该取决于每个处理过程需要多长时间,以便在发生停止时能够及时。

  

据推测,鉴于它已经是后台服务,我会同步处理行?换句话说,没有必要在后台线程上处理行?

同样,这是一个商业决策,但是,我可能会保持同步。

  

在帐户和运行权限方面我需要考虑什么?这是部署问题吗?

嗯,一切都取决于。 SQL Server是否在同一个盒子上?您使用的是Windows身份验证吗?如果SQL不在同一个框中,则必须使用用户帐户或Network Service。创建服务项目时,需要添加安装程序。创建项目后,您将获得一个组件类 - 在灰色屏幕上,右键单击并选择Add Installer。这将创建一个新的Component Class,其中已安装了两个模块。 serviceIntaller1具有服务名称,显示名称和描述以及启动类型(手动,自动等)。另一个是serviceProcessInstaller1,您可以在此决定使用哪个登录帐户。

  

还有其他问题需要注意什么?

呃,可能。但今天早上我还没喝咖啡。

真的,最重要的是计划如何让你的线程保持活跃并响应最终的OnStop请求。例如,如果您打算尝试使用SqlDependency类,则可能需要在OnStart中创建Manual或AutoResetEvent,启动线程并让线程设置SqlDependency然后阻止重置事件。然后,在您的OnStop中释放您的重置事件,以便您的线程可以清理并离开。在那之后,它只是一个滑冰山!

玩得开心!

答案 1 :(得分:2)

我的第一个问题是为什么触发器或SQL作业不够好?似乎要么就足够了。运行脚本以赶上处理然后打开触发器。

如果您已开始使用某项服务,那么Jim会首先提供有关作为控制台程序运行的建议。或者做这样的事情http://tech.einaregilsson.com/2007/08/15/run-windows-service-as-a-console-program/

同样http://topshelf-project.com/也是一个非常好的起点。

您可能还想处理服务的暂停和重启事件。再次像Jim说的那样在另一个线程中产生你的处理。我只需要在我的服务上修复一个很大的地方,我没有这样做,服务只会处于起始状态,你将无法轻易杀死它。 onStart方法必须返回。