【发布时间】:2019-12-12 06:16:19
【问题描述】:
我有一个 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);
}
}
}
}
自动取消方法将具有数据库访问和更新语句。
预期工作流程 -
它应该更新数据库中的所有条目并返回到 onStart 方法并每 5 秒轮询一次。
问题 -
每当它完成更新行并且如果它有时间(例如,如果它在最后一次迭代中在 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
帮助停止正在运行的实例的计时器,它应该按预期进行轮询。
【问题讨论】:
-
那么为什么你有 else 语句。为什么不处理您的更新并在最后写入日志文件?
-
因为如果更新语句中有任何中断,我应该在每次迭代的日志文件中打印它。让我们假设如果数据库没有要更新的新行,我需要打印 else 语句。我的问题是在每次更新执行后中断方法执行。
-
修改
DataTable时是否使用同一个锁? -
是的@TheodorZoulias
标签: c# multithreading timer