执行期间定时事件重叠
本文关键字:重叠 事件 定时 执行期 | 更新日期: 2023-09-27 17:59:15
我使用一个服务执行自动化任务时遇到问题。该服务使用计时器,并在20秒后执行。
执行的函数打开数据库,从中读取,通过网络发送值,接收响应并用该响应更新数据库。
它一直运行良好,直到我想对数据库中大约1000行执行自动化任务,但系统"失败"。在检查日志后,我发现该函数在间隔之后执行,即使前一个实例仍在执行。该功能应该发送一条消息,一些客户抱怨没有收到消息,而另一些客户则收到了多达六次的消息。
如果前一个实例仍在运行,是否有任何简单有效的方法可以确保函数不会运行。
如果我在函数中启动和停止时间,它只会将"已通过"的时间添加到间隔
这是代码
public partial class Service1 : ServiceBase
{
private Timer timer1 = null;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
timer1 = new Timer();
this.timer1.Interval = 20000;
this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Tick);
timer1.Enabled = true;
Library.WriteErrorLog("service has started");
}
private void timer1_Tick(object sender, ElapsedEventArgs e)
{
try
{
//retrieve data from database
//read rows
//Loop through rows
//send values through network
//receive response and update db
}
catch (Exception ex)
{
Library.WriteErrorLog(ex);
}
}
}
protected override void OnStop()
{
timer1.Enabled = false;
Library.WriteErrorLog("service has stopped");
}
}
private void timer1_Tick(object sender, ElapsedEventArgs e)
{
Timer timer = sender as Timer;
timer.Enabled = false; // stop timer
try
{
//retrieve data from database
//read rows
//Loop through rows
//send values through network
//receive response and update db
}
catch (Exception ex)
{
Library.WriteErrorLog(ex);
}
finally
{
timer.Enabled = true; // start timer again, no overlapping
}
}
您使用的是多线程System.Timers.Timer,它在每个Elapsed事件上从ThreadPool调用新线程上的timer1_Tick回调。使用变量来同步执行。
public partial class Service1 : ServiceBase
{
private Timer timer1 = null;
private long isTaskRunning = 0;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
timer1 = new Timer();
this.timer1.Interval = 20000;
this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Tick);
timer1.Enabled = true;
Library.WriteErrorLog("service has started");
}
private void timer1_Tick(object sender, ElapsedEventArgs e)
{
try
{
if (Interlocked.CompareExchange(ref isTaskRunning, 1, 0)==1)
{
return;
}
//retrieve data from database
//read rows
//Loop through rows
//send values through network
//receive response and update db
}
catch (Exception ex)
{
Library.WriteErrorLog(ex);
}
finally
{
Interlocked.Exchange(ref isTaskRunning, 0);
}
}
}
protected override void OnStop()
{
timer1.Enabled = false;
Library.WriteErrorLog("service has stopped");
}
}