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

时间:2010-05-12 15:20:59

标签: 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();

    }

来自SubscriptionService:

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服务的处理程序。

有人看到了吗?

1 个答案:

答案 0 :(得分:3)

在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();

}