ServiceBase.Run(ServiceBase [])方法是否异步运行数组中的所有服务?

时间:2015-08-03 06:17:20

标签: c# .net windows-services

ServiceBase[] servicesToRun;
            servicesToRun = new ServiceBase[]
            {
                new Service1(),
                new Service2()
            };
            ServiceBase.Run(servicesToRun);

这将如何运作? Service1是否会运行,当OnStart()完成后,Service2的OnStart()将会运行,或者两者都会同时运行? 如果是这种情况,我明确希望在运行OnStart之前完成Service1的Service2.OnStart(),我该怎么办?

这会起到什么作用:

ServiceBase.Run(new Service1())
ServiceBase.Run(new Service2())

1 个答案:

答案 0 :(得分:8)

你误解了ServiceBase.Run()实际做了什么。

来自the documentation

  

使用服务控制管理器(SCM)注册多个服务的可执行文件。

序列如下:

  • 收到一个(或两个)服务的启动请求。
  • SCM启动可执行文件。
  • 您的主函数调用ServiceBase.Run()。
  • SCM在新线程中调用OnStart()以获取与启动请求匹配的服务。 除非两个服务都已启动,否则OnStart()将为另一个服务而不是进行调用!

如果两个服务正在启动,那么调用OnStart()的顺序是不确定的,除非一个服务已配置为依赖另一个服务。配置这样的依赖是确保特定排序的唯一安全方法,任何欺骗,例如在一个OnStart()中等待来自另一个的信号可能导致SCM死锁。

如果只启动了一个服务,并且稍后启动了另一个服务,则SCM将在此时调用OnStart()以获取第二个服务。

在服务报告停止之前,对ServiceBase.Run()的调用不会返回。如果您已注册多个服务,则在停止所有服务之前不会返回。此时,您的流程将会退出。

请注意,您的第二个代码段肯定是错误的。第一次通话不会返回,直到Service1停止,此时第二次通话是非法的,可能会失败 - 无论如何,它肯定不会做任何有用的事情。

另请注意,如果两个服务无法相互独立运行,那么首先有两个服务可能没有意义。我能想到的唯一理由是,如果您希望用户能够在保持Service1运行的同时停止并启动Service2。