[英]Method inside System.Threading.Timer
我有一个Web服务器应用程序中的方法,该方法在后台每x分钟运行一些mysql查询,我搜索了一种很好的方法来执行此操作,并遇到了System.Threading.Timer类。 我设法在内部编写了该方法的代码,并使用日志跟踪了它的执行情况(每个查询和每个异常),但是我遇到了一个问题,我仍然无法理解正在发生的事情,问题是该方法何时需要实际做某事(当我在应用程序上有一条新记录时,该方法将获取它的数据并开始将其写入我的数据库中,但是只有在那x分钟运行了数据的情况下,它才会这样做,否则它将什么也不做)它停止了,查询或线程上都没有异常,我只是检查了日志,在x分钟内它应该在上面写了一些东西,根本什么也没有,有些东西扼杀了我的线程,我不明白什么/为什么,如果有人可以帮助我,我会感谢(抱歉我的英语不好),这是代码段:
using (StreamWriter sw = File.AppendText(path + @"\log_test.txt")) {
sw.WriteLineAsync("-------- LOG BEGIN --------" + Environment.NewLine);
try {
var timer = new System.Threading.Timer(async (ev) => {
bool sync = await AzureSync.Begin();
}, null, TimeSpan.Zero, TimeSpan.FromMinutes(2));
}
catch (Exception ex) {
sw.WriteLine(DateTime.Now + "**** ERROR ****" + Environment.NewLine);
sw.WriteLine(ex.ToString() + Environment.NewLine);
throw ex;
}
}
using
语句将太快关闭StreamWriter。 实际上,它将在设置新计时器后立即关闭StreamWriter。
因此,以这种方式编码的计时器启动时,计时器将无法写入日志。
您需要将设置sw
的using
语句移到计时器执行的自主方法中。
这应该对您更好。
var timer = new System.Threading.Timer(async (ev) => {
using (StreamWriter sw = File.AppendText(path + @"\log_test.txt")) {
sw.WriteLineAsync("-------- LOG BEGIN --------" + Environment.NewLine);
try {
bool sync = await AzureSync.Begin();
}
catch (Exception ex) {
sw.WriteLine(DateTime.Now + "**** ERROR ****" + Environment.NewLine);
sw.WriteLine(ex.ToString() + Environment.NewLine);
throw ex;
}
}
}, null, TimeSpan.Zero, 120000); //120000 milliseconds is 2 Minutes
同样在设置计时器时,我不确定TimeSpan.FromMinutes(2)是否适合您。 我相信基于以下代码示例: https : //docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/threading/thread-timers上一个参数以毫秒为单位。 因此,您要寻找的是120000。
需要考虑的其他事项
虽然上面的代码将“起作用”,但它遇到了一个严重的问题,@ Mukesh在其答案/建议中未曾提及。 如果后台进程引发异常,它将关闭IIS应用程序池进程并强制Web应用程序回收。 这几乎是永远不可取的。 上面代码的编写方式使得计时器proc中的任何异常都将导致该异常的发生,因为在捕获到异常并将其记录下来之后,它会将它们重新抛出。 应当认真考虑使用他的回答/建议中提到的第三方后台调度程序,或者至少要确保没有任何异常从计时器proc中逃脱,如下所示:
var timer = new System.Threading.Timer(async (ev) => {
try{
using (StreamWriter sw = File.AppendText(path + @"\log_test.txt")) {
sw.WriteLineAsync("-------- LOG BEGIN --------" + Environment.NewLine);
try {
bool sync = await AzureSync.Begin();
}
catch (Exception ex) {
sw.WriteLine(DateTime.Now + "**** ERROR ****" + Environment.NewLine);
sw.WriteLine(ex.ToString() + Environment.NewLine);
}
}
}catch{}; //swallow exception and prevent it from taking down the process/IIS app pool
}, null, TimeSpan.Zero, 120000); //120000 milliseconds is 2 Minutes
我只是给你一个建议:)。 您不应该在Web应用程序中执行后台作业。在IIS Web服务器中,应用程序可能会进入睡眠模式,或者在回收工作进程期间,您的后台任务将无法执行。 取而代之的是,您可以集成专门构建的库来实现后台作业,例如Hangfire , FLUENTSCHEDULER等,它们也具有非常好的仪表板功能。
为此,请参阅以下精彩文章。 如何在ASP.NET中运行后台任务
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.