执行过程中定时事件重叠 [英] Timed events overlapping during execution
问题描述
我用于执行自动任务的服务出现问题. 该服务使用计时器,并在20秒后执行.
I am having an issue with the a Service I used to perform automated tasks. The service uses a Timer and executes after 20 seconds.
执行的功能将打开数据库,从数据库中读取数据,通过网络发送值,接收响应并使用该响应更新数据库.
The function that is executed opens the database, reads from it, sends the values through the network, receives a response and updates the database with that response.
它一直运行良好,直到我想对数据库中的约1000行执行自动化任务,并且系统失败".检查日志后,我发现该功能在间隔执行后仍会执行,即使先前的实例仍在执行中.该功能应该发送一条消息,有些客户抱怨没有收到消息,而另一些则抱怨多达六次.
Its been working well until I wanted to carry out the automated tasks for about 1000 rows in the database and the system 'failed'. After checking my logs, I found out that the function executes after the interval even while a previous instance is still executing. The function is supposed to send a message and some clients complained of not getting a message while others got as much as six time.
是否有任何简单有效的方法来确保如果先前的实例仍在运行,该功能将不会运行.
Is there any simple and efficient way to make sure the function will not run if a previous instance is still running.
如果我在函数中开始和停止时间,它将仅将经过的"时间添加到间隔中
If I start and stop the time in the function, it will only add the "passed" time to the interval
这是代码
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");
}
}
推荐答案
您正在使用多线程System.Timers.Timer,它在每个Elapsed事件中从ThreadPool调用新线程上的timer1_Tick回调.使用变量来同步执行.
You are using the multi-threaded System.Timers.Timer which calls the timer1_Tick callback on a new thread from the ThreadPool on each Elapsed event. Use a variable to synchronize the execution.
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");
}
}
这篇关于执行过程中定时事件重叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!