gpt4 book ai didi

c# - System.Threading.Timer 中的方法

转载 作者:行者123 更新时间:2023-11-30 21:38:04 27 4
gpt4 key购买 nike

我在一个 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。

因此当计时器以这种方式编码时触发时,计时器将无法写入日志。

您需要移动 using设置语句 sw进入定时器执行的自主方法。

这应该更适合您。

 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://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/threading/thread-timers最后一个参数以毫秒为单位。所以 120000 就是你要找的。

需要考虑的其他事项
虽然上面的代码会“工作”,但它遇到了一个严重的问题,@Mukesh 在他的回答/建议中回避了这个问题。如果后台进程抛出异常,它将关闭 IIS 应用程序池进程并强制 Web 应用程序回收。这几乎是不可取的。上面代码的编写方式使得计时器过程中的任何异常都会导致这种情况发生,因为在捕获异常并记录它们之后,它会重新抛出它们。应该认真考虑使用他的回答/建议中提到的第 3 方后台调度程序,或者至少最好确保没有异常从定时器过程中逃脱,如下所示:

 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

关于c# - System.Threading.Timer 中的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46411067/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com