2010-05-12 4 views
3

J'ai un problème bizarre que je n'ai pas vu auparavant et je pense qu'il DOIT y avoir quelque chose de simple que je ne vois pas dans mon code.Plusieurs services Windows dans un seul projet = mystère

J'ai un projet avec 2 services Windows définis. Un que j'ai appelé DataSyncService, l'autre SubscriptionService. Les deux sont ajoutés au même programme d'installation de projet. Les deux utilisent un contrôle de minuterie de System.Timers.

Si je démarre les deux services ensemble, ils semblent fonctionner correctement. Les minuteries s'écoulent au moment approprié et tout a l'air correct. Cependant, si je commence chaque service individuellement, laissant l'autre arrêté, tout va mal. La minuterie s'écoule constamment et sur le mauvais service. En d'autres termes, si je démarre DataSyncService, le minuteur SubscriptionService se répète à plusieurs reprises. ... ce qui est évidemment étrange.

La configuration est similaire à ce que j'ai fait dans le passé, donc je suis vraiment perplexe. J'ai même essayé de supprimer le service et le redémarrage mais cela ne semble pas faire la différence. À ce stade, je pense que j'ai fait une erreur simple dans la façon dont je définis les services et mon cerveau ne me laisse pas le voir. Il doit créer une sorte de problème de threading qui provoque un service de course lorsque l'autre est arrêté. Voici le code ....

De Program.cs:

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

     }; 
     ServiceBase.Run(ServicesToRun); 
    } 

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

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

    } 

De AbonnementService:

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

    } 

Encore une fois, le problème est que le gestionnaire timer1_elapsed s'exécute constamment lorsqu'un seul des services est démarré. Et c'est le gestionnaire du service OPPOSITE.

Quelqu'un voit quelque chose?

+0

Qu'est-ce qui fait Program.cs? Je veux dire, je peux voir que ça commence les deux services, mais quand ça marche? – SqlRyan

+0

N'est-il pas étonnant que, lorsque vous publiez quelque chose comme ça dans le monde, la réponse vous frappe au visage. Dans les fichiers Service.Designer.cs méthodes InitializeComponent(), il me manque this.CanShutdown = true; ... et je ne devrais pas activer les minuteries ici puisque je le fais dans les gestionnaires OnStart. Oh, enfin, quelqu'un d'autre aura le même problème et j'espère qu'il trouvera ça. – Remoh

Répondre

3

Dans les méthodes, je manque

this.CanShutdown = true; 

fichiers Service.Designer.cs InitializeComponent() ... et je ne devrais pas permettre aux minuteries là depuis que je le fais dans les gestionnaires onStart.

il devrait donc être quelque chose comme:

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

} 
Questions connexes