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

Mef*_*to1 6 .net c# windows-services

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

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

这会诀窍:

ServiceBase.Run(new Service1())
ServiceBase.Run(new Service2())
Run Code Online (Sandbox Code Playgroud)

Har*_*ton 8

你误解了ServiceBase.Run()实际上是做什么的.

文档:

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

顺序如下:

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

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

如果仅启动了一个服务,并且稍后启动了另一个服务,则SCM将在该点为第二个服务调用OnStart().

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


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

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