c# – 重新启动依赖服务的服务?

前端之家收集整理的这篇文章主要介绍了c# – 重新启动依赖服务的服务?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
从 @L_404_0@开始,并正式注明相关的SO问题( Restart a windows services from C#Cannot restart a Service)以及关于重新启动一个服务的其他各种问题,我想知道什么是重新启动依赖服务的服务的最佳方法(例如消息队列,哪个消息排队触发器依赖或IIS,FTP发布和万维网发布所依赖的). mmc管理单元自动执行此操作,但代码似乎不提供相同的功能(至少不是那么容易).

MSDN documentation for Stop说:“如果任何服务依赖于此服务进行操作,则在停止此服务之前,它们将被停止.DependentServices属性包含依赖于该服务的服务集,”DependentServices返回一系列服务.假设StartService()和StopService()遵循示例中概述的约定,并且如上所述(除了它们直接接受ServiceController和TimeSpans),我开始于:

public static void RestartServiceWithDependents(ServiceController service,TimeSpan timeout)
{
    ServiceController[] dependentServices = service.DependentServices;

    RestartService(service,timeout); // will stop dependent services,see note below* about timeout...

    foreach (ServiceController dependentService in dependentServices)
    {
        StartService(dependentService,timeout);
    }
}

但是如果服务依赖关系嵌套(递归)或循环(如果还有可能)…如果服务A依赖于服务B1和服务B2,服务C1取决于服务B1,则似乎重新启动服务A通过这种方法将停止服务C1,但不会重新启动它…

为了使此示例图像更清晰,我将在服务mmc管理单元中遵循模型:

The following system components depend on [Service A]:
  - Service B1
    - Service C1
  - Service B2

有没有更好的方法解决这个问题,或者只是递归地进入并停止每个从属服务,然后在重新启动主服务后重新启动它们?

另外,依赖但是目前停止的服务将被列在DependentServices下?如果是这样,那么这个不会重启呢?如果是这样,我们还应该控制吗?这似乎变得越来越乱七八糟

*注意:我意识到超时在这里没有被完全正确应用(总体超时可能比预期的时间长很多倍),但现在不是我担心的问题 – 如果你想修复它,但不要只说“超时的破碎…”

更新:经过一些初步测试,我发现(确认)以下行为:

>停止其他服务(例如服务B1)依赖的服务(例如服务A)将停止其他服务(包括“嵌套”依赖性,例如服务C1)
> DependentServices在所有州(运行,停止等)中都包括依赖服务,并且还包括嵌套依赖关系,即Service_A.DependentServices将包含{Service B1,Service C1,Service B2}(按此顺序,因为C1取决于B1).
>启动依赖别人的服务(例如,服务B1依赖于服务A)也将启动必需的服务.

因此,上述代码可以简化(至少部分地),以停止主服务(将停止所有相关服务),然后重新启动最依赖的服务(例如,服务C1和服务B2)(或仅重新启动“全部”依赖服务 – 它将跳过已经开始的服务),但是这只是暂时推迟主服务的启动,直到其中一个依赖关系投诉,所以这不是真的有帮助.

现在看起来像只是重新启动所有的依赖是最简单的方法,但是忽略(现在)管理已经停止的服务,等等…

解决方法

好的,终于实现了.我已经把它作为一个单独的答案,因为我已经在我的问题的原始更新中得到这个结论,这是在第一个答案之前发布的.

再次,StartService(),StopService()和RestartService()方法遵循示例中概述的约定,并且在问题本身中已经引用(即它们包含启动/停止行为以避免“已经启动/停止”型异常)附加的是,如果传入一个服务(如下所述),则在检查其状态之前,将在该服务上调用Refresh().

public static void RestartServiceWithDependents(ServiceController service,TimeSpan timeout)
{
    int tickCount1 = Environment.TickCount; // record when the task started

    // Get a list of all services that depend on this one (including nested
    //  dependencies)
    ServiceController[] dependentServices = service.DependentServices;

    // Restart the base service - will stop dependent services first
    RestartService(service,timeout);

    // Restore dependent services to their prevIoUs state - works because no
    //  Refresh() has taken place on this collection,so while the dependent
    //  services themselves may have been stopped in the meantime,their
    //  prevIoUs state is preserved in the collection.
    foreach (ServiceController dependentService in dependentServices)
    {
        // record when the prevIoUs task "ended"
        int tickCount2 = Environment.TickCount;
        // update remaining timeout
        timeout.Subtract(TimeSpan.FromMilliseconds(tickCount2 - tickCount1));
        // update task start time
        tickCount1 = tickCount2;
        switch (dependentService.Status)
        {
            case ServiceControllerStatus.Stopped:
            case ServiceControllerStatus.StopPending:
                // This Stop/StopPending section isn't really necessary in this
                //  case as it doesn't *do* anything,but it's included for
                //  completeness & to make the code easier to understand...
                break;
            case ServiceControllerStatus.Running:
            case ServiceControllerStatus.StartPending:
                StartService(dependentService,timeout);
                break;
            case ServiceControllerStatus.Paused:
            case ServiceControllerStatus.PausePending:
                StartService(dependentService,timeout);
                // I don't "wait" here for pause,but you can if you want to...
                dependentService.Pause();
                break;
        }
    }
}

猜你在找的C#相关文章