views:

23

answers:

1

I'm having a bizarre issue that I haven't seen before and I'm thinking it MUST be something simple that I'm not seeing in my code.

I have a project with 2 windows services defined. One I've called DataSyncService, the other SubscriptionService. Both are added to the same project installer. Both use a timer control from System.Timers.

If I start both services together, they seem to work fine. The timers elapse at the appropriate time and everything looks okay. However, if I start either service individually, leaving the other stopped, everything goes haywire. The timer elapses constantly and on the wrong service. In other words, if I start the DataSyncService, the SubscriptionService timer elapses over and over. ...which is obviously strange.

The setup is similar to what I've done in the past so I'm really stumped. I even tried deleting both service and starting over but it doesn't seem to make a difference. At this point, I'm thinking I've made a simple error in the way I'm defining the services and my brain just won't let me see it. It must be creating some sort of threading issue that causes one service to race when the other is stopped. Here the code....

From Program.cs:

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

        };
        ServiceBase.Run(ServicesToRun);
    }

From 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;

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

    }

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

    }

Again, the problem is that the timer1_elapsed handler runs constantly when only one of the services is started. And it's the handler on the OPPOSITE service.

Anybody see anything?

+1  A: 

In the Service.Designer.cs files InitializeComponent() methods, I'm missing

this.CanShutdown = true; 

...and I shouldn't be enabling the timers there since I do it in the OnStart handlers.

So it should be something like:

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

}
Remoh