我遇到了一个我以前从未见过的奇怪问题,我认为它一定是一些我在代码中没有看到的简单问题。
我有一个项目,其中定义了 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/