我有一个Windows服务,该服务应每5秒钟对新条目进行一次数据库,然后更新日志文件。
我正在使用system.timers.timer类来调用我的数据库方法并每5秒调用自动结算。
protected override void OnStart(string[] args)
{
try
{
ServiceLogFile("Service is started at " + DateTime.Now);
timer.Elapsed += new ElapsedEventHandler(Autocancellation);
timer.Interval = Int32.Parse(ConfigurationManager.AppSettings["tracktime"]); //number in miliseconds
timer.Enabled = true;
}
catch(Exception ex)
{
ServiceLogFile("Error in {OnStart} :" + ex.ToString());
}
}
public void Autocancellation(object source, ElapsedEventArgs e)
{
try
{
lock (this)
{
//Database accesss
//select statement
//Adding to Data table
if(dt.Rows.Count>0)
{
//Update Statements
}
else
{
ServiceLogFile("There is no orders in the table Thread id :" +Thread.CurrentThread.ManagedThreadId);
}
}
}
}
自动结合方法将具有数据库访问和更新语句。
预期工作流程 -
它应该更新数据库中的所有条目,然后返回每5秒钟的ONSTART方法和轮询。
问题 -
每当它完成更新行并且有时间时(例如,在最后一次迭代时完成了2分钟的更新语句(,并且剩余的3分钟将打印"表中没有订单"。我无法停止打印它,直到完成整个计时器。
我尝试停止计时器 - 但这将导致它永远不会从Onstart方法再次对数据库进行轮询。
这是日志的样本
更新开始 -
Service is stopped at 8/4/2019 1:34:15 PM
Service is started at 8/4/2019 1:34:28 PM
Database check :8/4/2019 1:34:33 PM
{INFO} Cancelled Order {AccessionID} : A1
{INFO} Cancelled Order {AccessionID} : A2
{INFO} Cancelled Order {AccessionID} : A3
迭代结束 -
{INFO} Cancelled Order {AccessionID} : A49997
{INFO} Cancelled Order {AccessionID} : A49998
{INFO} Cancelled Order {AccessionID} : A49999
{INFO} Cancelled Order {AccessionID} : A50000
Database check :8/4/2019 1:51:53 PM
There is no orders in the table Thread id :4
Database check :8/4/2019 1:51:53 PM
There is no orders in the table Thread id :3
Database check :8/4/2019 1:51:53 PM
There is no orders in the table Thread id :7
如果我们可以看到上面的日志以相同的方法打印没有记录的方法。我尝试杀死线程和返回语句。什么都没有。
此迭代时间(5秒(之后这将返回到Onstart和民意调查5秒钟,日志很完美 -
Database check :8/4/2019 1:52:04 PM
There is no orders in the table Thread id :96
Database check :8/4/2019 1:52:09 PM
There is no orders in the table Thread id :97
Database check :8/4/2019 1:52:14 PM
帮助停止运行实例的计时器,并应按预期进行轮询。
我将AutoReset
属性设置为False
并在没有更多记录后重新启动计时器。原因是您的Autocancellation
可能在忙于处理记录时从不同的线程中多次调用。
来自msdn:
获取或设置布尔值,指示计时器是否应提高 经过的事件仅一次(false(或反复(true(。
protected override void OnStart(string[] args)
{
try
{
ServiceLogFile("Service is started at " + DateTime.Now);
timer.AutoReset = false;
timer.Elapsed += new ElapsedEventHandler(Autocancellation);
timer.Interval = Int32.Parse(ConfigurationManager.AppSettings["tracktime"]); //number in miliseconds
timer.Enabled = true;
timer.Start();
}
catch(Exception ex)
{
ServiceLogFile("Error in {OnStart} :" + ex.ToString());
}
}
public void Autocancellation(object source, ElapsedEventArgs e)
{
try
{
lock (this)
{
//Database accesss
//select statement
//Adding to Data table
if(dt.Rows.Count>0)
{
//Update Statements
}
else
{
ServiceLogFile("There is no orders in the table Thread id :" +Thread.CurrentThread.ManagedThreadId);
}
}
}
finally
{
// in anycase, start the timer again. In this pattern, you will not get
// any calls until the processing is finished.
timer.Start();
}
}