我正在进入 Windows 服务并查看一些教程,但它们都非常愚蠢。它们通常涉及在重写的 OnStart 方法中打印一些内容。这听起来像它被调用一次。现在我应该把需要连续运行的代码放在哪里?
3 回答
服务类中的所有 On... 方法都应尽快返回。每当 Windows 服务控制器与您的服务交互时,它们最终都会被调用,并且服务控制器将等待成功返回。每当您使用服务控制面板小程序并启动或停止服务时,您看到的进度条就是在等待该服务的等效 OnStart 或 OnStop 返回时显示的内容。
所以在 OnStart 中要做的典型事情是以下一项或多项:
- 启动一个单独的线程来执行您的服务将执行的恒定任务
- 设置一个计时器(
System.Threading.Timer
各种),它将定期执行您的服务定期执行的任何操作(可能轮询某些状态) - 开始在网络端口上异步侦听,可能使用 TcpListener 或 UdpClient
- 订阅一些系统事件
在任何这些情况下,您的服务任务都是异步执行的,并且您会立即从 OnStart 退出。但请记住跟踪您的线程、计时器、TcpListener 或其他任何东西,以便您可以在 OnStop(以及可选的 OnPause 和 OnContinue)中与其交互。通常要做的事情是处理任何计时器(因此它们不会再触发),关闭所有套接字或侦听器,然后设置 ManualResetEvent。您正在运行的任何线程都应定期检查此事件并在收到信号后退出。如果您想确保成功关闭服务并冒可能丢失数据的风险,您可以加入具有合理超时(通常为 30 秒)的任何正在运行的线程,然后中止在超时到期后仍在运行的任何线程。
与具有多个类的任何其他项目相同 - 您将其放在单独的项目中。
“Windows 服务”项目应该只包含启动服务的样板文件、作为服务一部分的任何计时器等等。将其余部分放在另一个项目中允许您稍后在桌面应用程序、Web 应用程序、WCF 服务等中使用您的业务逻辑。
为了以正确的方式创建任何 Windows 服务,我坚持使用TopShelf库。它是 IoC 友好的,您可以将 Windows 服务基础结构代码与服务逻辑完全分开。您还可以将该服务作为控制台应用程序运行,然后将其转换为生产环境中的 Windows 服务。我认为这是创建 Windows 服务的“THE”方式,并且永不回头。