特定时间间隔内的重复性任务?

时间:2012-11-30 15:02:15

标签: c# .net asp.net-mvc timer scheduled-tasks

例如,我想以特定的时间间隔(每小时或每日任务)调用一个函数。

我已经在使用Timer了。但只要我的本地服务器正常工作,它就能工作。例如:

public static void StartYahooWeatherManager()
{
    Timer t = new Timer(1000 * 60 * 60 * 6  /* 6 hours */);
    t.Elapsed += new ElapsedEventHandler(WriteYahoWeatherRssItemToDb);
    t.Start();
}

private static void WriteYahoWeatherRssItemToDb(object o, ElapsedEventArgs e)
{
    YahooWeatherManager.InsertYahooWeatherRssItem(YahooWeatherManager.GetYahooWeatherRssItem());
}

我以6小时为间隔向db发送天气信息。项目已经在主持人。只要我的计算机本地服务器正在运行,Timer事件就会起作用。

问题:

我的代码有什么问题? (或者在WebProject中使用计时器的逻辑错误?)为什么计时器仅在本地服务器工作时工作?

管理时间间隔任务的最佳方法是什么? (不需要asp.net)

我希望,我可以解释这个问题。感谢。

3 个答案:

答案 0 :(得分:7)

计时器停止的原因是因为此计时器在您的ASP.NET应用程序中运行,该应用程序本身托管在Web服务器上。当此服务器停止或回收应用程序时,AppDomain将与您可能已启动的所有线程一起关闭。这就是为什么在ASP.NET应用程序中编写重复的后台任务是一个非常糟糕的主意。 Phil Haack blogged about the dangers

执行此操作的正确方法是在ASP.NET应用程序之外的单独进程中托管此代码。这可以是Windows服务或控制台应用程序,它计划使用例如Windows调度程序定期运行。这样可以保证代码始终运行。

答案 1 :(得分:2)

我的建议是创建一个使用计时器的Windows服务,或创建一个普通的应用程序并创建一个计划任务,以便在您需要的时间间隔内运行它。此StackOverflow帖子可以帮助您:

Windows service and timer

答案 2 :(得分:0)

您可以禁用您的asp.net应用所属的应用程序池的回收。内存泄漏在.Net中很少见,因此大多数情况下你可以依赖GC。这也将在回收后消除热身,并且几乎不费力地改善用户体验。

另一个好的解决方案是创建控制台应用程序并在Windows“Task Scheduler”中安排它。您将有一个很好的UI来管理何时以及如何运行。维护此类任务要比“Windows Service”容易得多,并且需要编写更少的代码。