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

Does ServiceBase.Run(ServiceBase[] ) method run all services in array asynchronously?

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

这将如何运作? Service1 是 运行,当它的 OnStart() 完成时,Service2 的 OnStart() 将是 运行,还是两者同时 运行? 如果是这样,我明确希望 Service1 的 OnStart 在 运行 宁 Service2.OnStart() 之前完成,我该怎么办?

这样做有用吗:

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

您误解了 ServiceBase.Run() 的实际作用。

来自the documentation

Registers the executable for multiple services with the Service Control Manager (SCM).

顺序是这样的:

  • 收到一项(或可能两项)服务的启动请求。
  • SCM 启动可执行文件。
  • 您的主函数调用 ServiceBase.Run()。
  • SCM 在新线程中为匹配启动请求的服务调用OnStart()。 除非同时启动两个服务,否则 不会 为另一个服务调用 OnStart()!

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

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

对 ServiceBase.Run() 的调用不会 return 直到服务报告它已停止。如果您注册了多个服务,则在所有服务停止后才会return。届时您的进程将退出。


请注意,您的第二个代码段肯定是错误的。在 Service1 停止之前,第一次调用不会 return,此时第二次调用是非法的并且可能会失败 - 无论如何,它肯定不会做任何有用的事情。

另请注意,如果这两项服务不能 运行 彼此独立,那么一开始就拥有这两项服务可能毫无意义。我能想到的唯一明智的情况是,如果您希望用户能够在离开 Service1 时停止和启动 Service2 运行ning.