c# - 实现 Windows 服务 - 如何满足这些要求?

标签 c# sql-server windows-services

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

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

所以我的具体问题是:

  • 如何让它保持事件状态并在写入新行时对其做出响应?我可以使用某种类型的 SQLDependency 对象来有效地处理新行吗?
  • 如何处理正常启动和关闭?
  • 从数据库中获取行时,我应该获取所有正在等待处理的行,还是一次只获取一个?
  • 假设它已经是后台服务,我会同步处理行吗?换句话说,不需要在后台线程上处理行?
  • 我需要考虑哪些帐户及其运行权限?这是部署问题吗?
  • 还有其他需要注意的问题或事项吗?

感谢您的任何建议。

附言。除了使用 Windows 服务来实现此目的之外,还有其他合理的替代方法吗?

最佳答案

编写 Windows 服务并没有那么困难,但不可否认,乍一看似乎令人生畏。

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

现在,开始服务。当然,使用 Visual Studio 创建一个 Windows 服务项目。

How do I keep it alive and responding to new rows as they're written? Can I use a SQLDependency object of some kind to efficiently process new rows?

好吧,我不确定你是否可以,但我可以告诉你你需要什么。你将需要一个线程。如果您不在 OnStart 事件中创建新线程,您的服务将立即停止。该线程可以直接使用 .NET 的众多线程机制之一创建,也可以通过某种计时器、FileSystemWatcher(可能不适用于您)或其他方式间接创建。

How do I handle graceful startup and shut down?

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

When picking up rows from the db, should I fetch all that are awaiting processing, or just one at a time?

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

Presumably, given that it is already a background service, I would process rows synchronously? In otherwords, there is no need to process rows on background threads?

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

What do I need to think about in terms of accounts and under what permissions it runs? Is this a deployment issue?

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

Any other gotchas or things to be aware of?

嗯,大概吧。但是今天早上我还没喝咖啡。

实际上,最重要的事情是规划如何让您的线程保持事件状态并响应最终的 OnStop 请求。例如,如果您要尝试使用 SqlDependency 类,您可能需要在 OnStart 中创建一个 Manual 或 AutoResetEvent,启动您的线程并让您的线程设置 SqlDependency然后阻止重置事件。然后,在您的 OnStop 中释放您的重置事件,以便您的线程可以清理并离开。之后,就只是滑下山了!

玩得开心!

关于c# - 实现 Windows 服务 - 如何满足这些要求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5677122/

相关文章:

c# - 混淆包含数据绑定(bind)到内部类属性的程序集

c - 调试 C Windows 服务中的启动问题

sql - 按 SQL 中的计算字段进行分组

c# - 如何从服务可靠地捕获 Windows 登录、注销、锁定和解锁事件?

visual-studio-2012 - 如何创建 InstallShield LE 项目来安装 Windows 服务?

c# - 在 C# 中保存数据结构

javascript - 从 javascript 添加 ASP.Net 标签,为什么会起作用?

c# - PROCESSOR_ARCHITECTURE 在某些 32 位进程中返回 AMD64

sql - 使用 SQL 脚本在 SQL Server 中导入 DBF 文件

sql-server - 连接日志