我已经阅读了很多与 Windows 服务和计时器使用相关的帖子,但我还没有找到任何原因导致我的事件处理程序仍然被触发。谁能指出我正确的方向?我想知道为什么会发生这种情况,所以我知道将来如何避免这种情况。
编辑:永远不会调用 onError 事件处理程序(或者我会在事件日志中看到该事件)。
计时器: System.Timers.Timer
ServiceBase: System.ServiceProcess.ServiceBase
这是抽象类:
public abstract class ABCService : ServiceBase
{
// Members
protected Timer invocationTimer;
protected Timer wellnessTimer;
protected FileSystemWatcher fsw;
// Constructors
protected ABCService()
{
invocationTimer = new Timer();
wellnessTimer = new Timer();
fsw = null;
invocationTimer.AutoReset = false;
invocationTimer.Interval = 30000; // 30 seconds
invocationTimer.Elapsed += new ElapsedEventHandler(invocationTimer_Elapsed);
wellnessTimer.AutoReset = false;
wellnessTimer.Elapsed += new ElapsedEventHandler(wellnessTimer_Elapsed);
}
// Methods
protected void invocationTimer_Elapsed(object o, ElapsedEventArgs args)
{
try
{
// log to event log
invocationTimer.Stop();
if ((new FileInfo(fsw.Path + "\\" + fsw.Filter)).Exists)
{
onCreated(this, new FileSystemEventArgs(WatcherChangeTypes.Created, fsw.Path, fsw.Filter));
}
}
catch (Exception x)
{
onError(this, new ErrorEventArgs(x));
}
}
protected void wellnessTimer_Elapsed(object o, ElapsedEventArgs args)
{
try
{
// log to event log
wellnessTimer.Stop();
wellnessTimer.Interval = 60000; // ms
if (fsw != null)
{
fsw.Dispose();
}
fsw = new FileSystemWatcher(ConfigurationManager.AppSettings["pathKey"], ConfigurationManager.AppSettings["filterKey"]);
invocationTimer.Start();
}
catch (Exception x)
{
onError(this, new ErrorEventArgs(x));
}
}
protected abstract void onCreated(object o, FileSystemEventArgs args);
protected virtual void onError(object o, ErrorEventArgs args)
{
// log to event log
wellnessTimer.Start();
}
protected override void OnStart(string[] args)
{
// log to event log
wellnessTimer.Interval = 5000; // 5 seconds
wellnessTimer.Start();
}
protected override void OnStop()
{
// log to event log
wellnessTimer.Stop();
}
}
这是一个实例类:
public partial class Service1 : ABCService
{
// Members
private static object locket = new object();
private static DateTime LAST_RUN_TIME = DateTime.Now.AddSeconds(-10);
// Constructors
public Service1()
{
InitializeComponent();
}
// Methods
protected override void onCreated(object o, FileSystemEventArgs args)
{
lock (locket)
{
// log to event log
if ((DateTime.Now - LAST_RUN_TIME).Seconds >= 10)
{
// do stuff
}
else
{
// log to event log
invocationTimer.Stop();
invocationTimer.Start();
}
}
}
}
这是部分类的自动生成代码:
partial class Service1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// Service1
//
this.ServiceName = "Service1";
}
#endregion
}
那么究竟发生了什么?我正在查看我的事件日志,我看到每分钟调用一次 wellnessTimer 事件处理程序。
这是我认为正在发生的事情,但我显然错了:
1. Service is started via MMC
2. OnStart() method is invoked
3. wellnessTimer interval is set to 5 seconds
4. wellnessTimer start method is invoked
5. wellnessTimer_Elapsed event handler is invoked
6. wellnessTimer stop method is invoked
7. wellnessTimer interval is set to 5 minutes
8. invocationTimer start method is invoked
9. 30 seconds later, the invocationTimer_Elapsed method is invoked
10. invocationTimer stop method is invoked
此时,此实例的两个计时器仍应存在,但应禁用。我通过附加到 Visual Studio 2010 中的进程对此进行了调试,并为传递给事件处理程序的对象(发送者)标记了一个 ID。它与实例是同一个对象。此外,Locals 窗口中的两个计时器都将其启用属性设置为 false。
这让我觉得我错误地使用了继承,或者线程正在发生一些事情。我在这两件事上都不是最好的,但如果是因为他们,请告诉我,以便我学习。
提前感谢大家。
编辑#2:这是一些跟踪数据......
'o' 表示传递给事件处理程序的对象
ABCService() method invoked <--
ABCService() method invoked -->
Service1() method invoked <--
Service1() method invoked -->
OnStart() method invoked <--
OnStart() method invoked -->
wellnessTimer_Elapsed() method invoked <--
((System.Timers.Timer) o).Enabled = False
((System.Timers.Timer) o).Interval = 5000
this.wellnessTimer.Enabled = False
this.wellnessTimer.Interval = 5000
wellnessTimer_Elapsed() method invoked -->
invocationTimer_Elapsed() method invoked <--
((System.Timers.Timer) o).Enabled = False
((System.Timers.Timer) o).Interval = 30000
this.invocationTimer.Enabled = False
this.invocationTimer.Interval = 30000
invocationTimer_Elapsed() method invoked -->
wellnessTimer_Elapsed() method invoked <--
((System.Timers.Timer) o).Enabled = False
((System.Timers.Timer) o).Interval = 60000
this.wellnessTimer.Enabled = False
this.wellnessTimer.Interval = 60000
wellnessTimer_Elapsed() method invoked -->
invocationTimer_Elapsed() method invoked <--
((System.Timers.Timer) o).Enabled = False
((System.Timers.Timer) o).Interval = 30000
this.invocationTimer.Enabled = False
this.invocationTimer.Interval = 30000
invocationTimer_Elapsed() method invoked -->