在ASP.NET中使用System.Timers.Timer

11
我在一个asp.net网站中使用以下代码。
在应用程序初始化时,我调用InitializeTimer()一次。
该代码的目标是每个小时运行DoWork()一次。
我还希望代码在每个循环中以不同的时间执行,因此我添加了随机部分。
我得到的结果很奇怪,我找不到为什么会发生的解释。
代码在2小时后执行函数,然后再次在2小时后执行,然后在3小时后执行,然后在2小时后又执行了2小时。****
有人能解释原因吗?
using System.Timers;
....
private static random = new Random();
....
public static void InitializeTimer()
{
    tTimer = new Timer();
    tTimer.AutoReset = true;
    tTimer.Interval = TimeSpan.FromHours(1.0).TotalMilliseconds;
    tTimer.Elapsed += new ElapsedEventHandler(ClassName1.tMailer_Elapsed);
    tTimer.Start();
}

private static void tTimer_Elapsed(object sender, ElapsedEventArgs e)
{
    tTimer.Interval += random.Next(-5, 5);

    DoWork();
}

更新:

  1. 请勿发布“使用Windows服务”或“计划任务”的帖子。 我的问题是针对以下代码的,我不需要更好的替代方案。 此外,在此测试期间(10小时),网站访问量很高,IIS池没有重新启动!

  2. 根据以下MSDN:(http://msdn.microsoft.com/en-us/library/system.timers.timer.interval.aspx)

如果在Timer启动后设置时间间隔,则计数将被重置。例如,如果将时间间隔设置为5秒,然后将Enabled属性设置为true,则计数从设置Enabled的时间开始。如果在计数为3秒时将时间间隔重置为10秒,则Elapsed事件第一次在Enabled设置为true后的13秒引发。

重置Elapsed函数中的间隔是否可能导致问题?

这意味着当调用tTimer_Elapsed函数时,计数为1小时(减去几毫秒), 而我的代码“tTimer.Interval + = random.Next(-5,5);”会将另一个完整的小时添加到Interval中吗?


如果您去掉随机部分,代码是否按预期工作? - mpeterson
我不知道,代码正在生产服务器上运行,现在我无法更改它(未来几天也不能),这就是为什么我提出问题寻找解释的原因。 - RuSh
那是否意味着在本地测试时它能如预期执行? - mpeterson
那么换句话说,您是在要求我们帮助您以错误的方式完成它,尽管微软建议不要在ASP.NET中使用System.Timers吗?(请参见https://learn.microsoft.com/en-us/dotnet/api/system.timers.timer?view=netframework-3.5) - RashadRivera
4个回答

7
ASP.NET应用程序在不使用时会被关闭。如果有人访问您的网站,然后没有更多的访问,它可能会被关闭。您的计时器将不会触发。
对于此类维护工作,您需要使用Windows计划任务或Windows服务。

感谢输入。在测试期间,网站或 IIS 池未重新启动。我认为我的代码有问题。 - RuSh
@sharru IIS会在没有用户干预的情况下回收你的应用程序。 - Jader Dias
1
我知道这件事,我记录了这些事件,没有重新启动发生。 - RuSh

3

看看这个... Jeff Atwood实际上讨论了类似的事情。我猜它起作用了,但据Jeff说,该网站已经超出了这种方法的范围,所以他们转向了专用任务。


是的,可能唯一能够起作用的原因是SO在IIS中从未闲置... - Ian Kemp

1

这并没有帮助到提问者的问题,也就是计时器由于IIS将应用程序池置于空闲状态而无法按正确的间隔触发。 - Ian Kemp

0

我赞同Sam的建议,使用Windows计划任务每小时访问一个页面。我曾经尝试过很多次让它工作,但只是勉强能用。后来我使用了计划任务,从此再也没有出现过问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接