c# - 单个项目中的多个 Windows 服务 = 神秘

标签 c# windows-services

我遇到了一个我以前从未见过的奇怪问题,我认为它一定是一些我在代码中没有看到的简单问题。

我有一个项目,其中定义了 2 个 Windows 服务。一个我称为 DataSyncService,另一个称为 SubscriptionService。两者都被添加到同一个项目安装程序中。两者都使用 System.Timers 中的定时器控件。

如果我同时启动这两个服务,它们似乎工作正常。计时器在适当的时间结束,一切看起来都很好。但是,如果我单独启动其中一项服务,而让另一项服务停止,一切都会变得一团糟。计时器在错误的服务上不断流逝。换句话说,如果我启动 DataSyncService,SubscriptionService 计时器就会一遍又一遍地计时。 ...这显然很奇怪。

设置与我过去所做的类似,所以我真的很困惑。我什至尝试删除这两个服务并重新开始,但这似乎没有什么不同。在这一点上,我想我在定义服务的方式上犯了一个简单的错误,我的大脑就是不让我看到它。它一定是造成了某种线程问题,导致一项服务在另一项服务停止时竞争。这里的代码....

来自 Program.cs:

static void Main()
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new DataSyncService(),
            new SubscriptionService()

        };
        ServiceBase.Run(ServicesToRun);
    }

来自 ProjectInstaller.designer.cs:

private void InitializeComponent()
    {
        this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
        this.dataSyncInstaller = new System.ServiceProcess.ServiceInstaller();
        this.subscriptionInstaller = new System.ServiceProcess.ServiceInstaller();
        // 
        // serviceProcessInstaller1
        // 
        this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
        this.serviceProcessInstaller1.Password = null;
        this.serviceProcessInstaller1.Username = null;
        // 
        // dataSyncInstaller
        // 
        this.dataSyncInstaller.DisplayName = "Data Sync Service";
        this.dataSyncInstaller.ServiceName = "DataSyncService";
        this.dataSyncInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
        // 
        // subscriptionInstaller
        // 
        this.subscriptionInstaller.DisplayName = "Subscription Service";
        this.subscriptionInstaller.ServiceName = "SubscriptionService";
        this.subscriptionInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
        // 
        // ProjectInstaller
        // 
        this.Installers.AddRange(new System.Configuration.Install.Installer[] {
        this.serviceProcessInstaller1,
        this.dataSyncInstaller,
        this.subscriptionInstaller});

    }

private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1;
    private System.ServiceProcess.ServiceInstaller dataSyncInstaller;
    private System.ServiceProcess.ServiceInstaller subscriptionInstaller;

来自 DataSyncService.cs:

public static readonly int _defaultInterval = 43200000;
    //log4net.ILog log;

    public DataSyncService()
    {
        InitializeComponent();

        //log = LogFactory.Instance.GetLogger(this);
    }

    protected override void OnStart(string[] args)
    {
        timer1.Interval = _defaultInterval; //GetInterval();
        timer1.Enabled = true;
        EventLog.WriteEntry("MyProj", "Data Sync Service Started", EventLogEntryType.Information);
        //log.Info("Data Sync Service Started");
    }

    private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        EventLog.WriteEntry("MyProj", "Data Sync Timer Elapsed.", EventLogEntryType.Information);

    }

private void InitializeComponent()
    {
        this.timer1 = new System.Timers.Timer();
        ((System.ComponentModel.ISupportInitialize)(this.timer1)).BeginInit();
        // 
        // timer1
        // 
        this.timer1.Enabled = true;
        this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Elapsed);
        // 
        // DataSyncService
        // 
        this.ServiceName = "DataSyncService";
        ((System.ComponentModel.ISupportInitialize)(this.timer1)).EndInit();

    }

来自订阅服务:

public static readonly int _defaultInterval = 300000;
    //log4net.ILog log;

    public SubscriptionService()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        timer1.Interval = _defaultInterval; //GetInterval();
        timer1.Enabled = true;
        EventLog.WriteEntry("MyProj", "Subscription Service Started", EventLogEntryType.Information);
        //log.Info("Subscription Service Started");
    }

    private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        EventLog.WriteEntry("MyProj", "Subscription Service Time Elapsed", EventLogEntryType.Information);
    }

private void InitializeComponent()  //in designer
    {
        this.timer1 = new System.Timers.Timer();
        ((System.ComponentModel.ISupportInitialize)(this.timer1)).BeginInit();
        // 
        // timer1
        // 
        this.timer1.Enabled = true;
        this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Elapsed);
        // 
        // SubscriptionService
        // 
        this.ServiceName = "SubscriptionService";
        ((System.ComponentModel.ISupportInitialize)(this.timer1)).EndInit();

    }

同样,问题是当只有一个服务启动时,timer1_elapsed 处理程序会持续运行。它是 OPPOSITE 服务上的处理程序。

有人看到了什么吗?

最佳答案

在 Service.Designer.cs 文件中,我缺少 InitializeComponent() 方法

this.CanShutdown = true; 

...我不应该在那里启用计时器,因为我是在 OnStart 处理程序中启用的。

所以它应该是这样的:

private void InitializeComponent()
{
    this.timer1 = new System.Timers.Timer();
    ((System.ComponentModel.ISupportInitialize)(this.timer1)).BeginInit();
    // 
    // timer1
    // 

    this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Elapsed);
    // 
    // DataSyncService
    // 
    this.ServiceName = "DataSyncService";
    this.CanShutdown = true;
    ((System.ComponentModel.ISupportInitialize)(this.timer1)).EndInit();

}

关于c# - 单个项目中的多个 Windows 服务 = 神秘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2820216/

相关文章:

c# - 尝试使用 char * 数据编码结构,但数据为空

C# 7 模式匹配

c# - MVC 'Find' 方法需要很长时间(甚至在发布时)? (使用迷你配置文件)

mongodb - MongoDB 服务因服务特定错误而终止无法创建另一个系统信号量

.Net Windows 服务和 InstallState 文件 - 真的需要吗?

c# - 将c#解密方法转换为android

c# - 在 C# 中,如何在运行时检查对象是否属于某种类型?

在没有 Visual Studio 的情况下创建 Windows 服务

c# - 从 Windows Server 2008 访问 Windows Server 2003 共享文件夹

service - 我在 Windows 服务中收到 system.configuration.settingspropertynotfoundexception 错误