You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置多个Windows Service 解决启动后互相关停运行异常问题

Windows 多服务启动互斥、自动停止问题排查

我此前参照视频教程创建Windows Service,业务逻辑为:定义Model后在Controller中获取Model构造待发送数据,再在Service中调用该Controller。
之后我创建了安装程序,一共部署3个服务,通过在每个服务开头添加[RunInstaller(true)]完成创建,我将服务设置为非手动启动、做了异常预处理后尝试启动服务。但出现了启动其中一个服务后另一个就会关停的问题,偶尔能成功启动3个服务,但很快所有服务又会全部停止运行。

相关代码

ProjectInstaller 截图

ProjectInstaller截图

ProjectInstaller.Designer.cs

partial class ProjectInstaller
{
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary> 
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Component Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
        this.AccountService = new System.ServiceProcess.ServiceInstaller();
        this.FinInfoPrevYearService = new System.ServiceProcess.ServiceInstaller();
        this.GetFinancialInfoService = new System.ServiceProcess.ServiceInstaller();
        // 
        // serviceProcessInstaller1
        // 
        this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalService;
        this.serviceProcessInstaller1.Password = null;
        this.serviceProcessInstaller1.Username = null;
        this.serviceProcessInstaller1.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.serviceProcessInstaller1_AfterInstall);
        // 
        // AccountService
        // 
        this.AccountService.ServiceName = "AccountService";
        this.AccountService.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.AccountService_AfterInstall);
        // 
        // FinInfoPrevYearService
        // 
        this.FinInfoPrevYearService.ServiceName = "FinInfoPrevYearService";
        this.FinInfoPrevYearService.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.FinInfoPrevYearService_AfterInstall);
        // 
        // GetFinancialInfoService
        // 
        this.GetFinancialInfoService.ServiceName = "GetFinancialInfoService";
        this.GetFinancialInfoService.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.GetFinancialInfoService_AfterInstall);
        // 
        // ProjectInstaller
        // 
        this.Installers.AddRange(new System.Configuration.Install.Installer[] {
        this.serviceProcessInstaller1,
        this.AccountService,
        this.FinInfoPrevYearService,
        this.GetFinancialInfoService});

    }

    #endregion

    private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
    private System.ServiceProcess.ServiceInstaller AccountService;
    private System.ServiceProcess.ServiceInstaller FinInfoPrevYearService;
    private System.ServiceProcess.ServiceInstaller GetFinancialInfoService;
}

ProjectInstaller.cs

[RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer
{
    public ProjectInstaller()
    {
        InitializeComponent();
    }

    private void serviceProcessInstaller1_AfterInstall(object sender, InstallEventArgs e)
    {

    }

    private void AccountService_AfterInstall(object sender, InstallEventArgs e)
    {

    }

    private void GetFinancialInfoService_AfterInstall(object sender, InstallEventArgs e)
    {

    }

    private void FinInfoPrevYearService_AfterInstall(object sender, InstallEventArgs e)
    {

    }
}

单服务示例截图

单服务示例截图

排查与修复方案

  • 配置维度:确认三个服务没有占用同一个端口、独占文件、全局互斥锁等互斥系统资源;显式给每个服务的StartType属性设置为Automatic或AutomaticDelayedStart,不要留默认配置。
  • 逻辑维度:每个服务的OnStart方法中必须启动独立的后台常驻线程保活,不要让OnStart主线程执行完直接退出,也不要阻塞OnStart主线程超过30秒(Windows服务启动超时阈值)。
  • 异常排查:给每个服务单独配置独立的日志输出,捕获服务退出前的异常堆栈,确认是否是多个服务共用静态资源、数据库连接池出现竞争冲突导致崩溃;排查是否所有服务都注册了同一个全局命名互斥体(Mutex),导致实例互斥启动失败。

内容的提问来源于stack exchange,提问作者Gonçalo Nogueira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 17:36:05