运行计划任务的最佳方式

时间:2009-02-12 19:08:45

标签: asp.net windows iis scheduled-tasks

今天我们构建了一个控制台应用程序,用于运行ASP.NET网站的计划任务。但我认为这种方法有点容易出错且难以维护。如何执行计划任务(在Windows / IIS / ASP.NET环境中)

更新:

任务示例:

  • 从数据库中的电子邮件队列发送电子邮件
  • 从数据库中删除过时的对象
  • 从Google AdWords检索统计信息并填写数据库中的表格。

16 个答案:

答案 0 :(得分:126)

This technique by Jeff Atwood for Stackoverflow是我遇到过的最简单的方法。它依赖于“缓存项删除”回调机制构建到ASP.NET的缓存系统

更新:Stackoverflow已超出此方法。它只适用于网站运行,但这是一种非常简单的技术,对很多人都有用。

另请查看Quartz.NET

答案 1 :(得分:70)

网站的所有任务(需要安排)都保存在网站内,并从特殊页面调用。然后我写了一个简单的Windows服务,每隔一段时间调用一次这个页面。页面运行后,它返回一个值。如果我知道还有更多的工作要做,我会马上再次运行页面,否则我会在一段时间内运行它。这对我来说非常有效,并且我的所有任务逻辑都与Web代码保持一致。在编写简单的Windows服务之前,我使用Windows调度程序每x分钟调用一次页面。

另一种方便的方法是使用Pingdom之类的监控服务。将他们的http检查指向运行您的服务代码的页面。让页面返回结果,然后可以用来触发Pingdom在出现问题时发送警报消息。

答案 2 :(得分:30)

创建custom Windows Service

我将一些任务关键任务设置为计划的控制台应用程序,并发现它们很难维护。我创建了一个带有'heartbeat'的Windows服务,可以每隔几分钟检查一次我的数据库中的计划。它运作得很好。

话虽如此,我仍然使用预定的控制台应用程序来执行大多数非关键维护任务。如果没有损坏,请不要修理它。

答案 3 :(得分:17)

我发现这对所有参与者都很容易:

  • 创建Web服务方法,例如DoSuchAndSuchProcess
  • 创建一个调用此web方法的控制台应用程序。
  • 在任务计划程序中安排控制台应用程序。

使用此方法,您的Web应用程序中包含所有业务逻辑,但您具有Windows任务管理器或任何其他商业任务管理器的可靠性,可将其启动并记录任何返回信息(如执行报告)。使用Web服务而不是发布到页面有一些优势,因为从Web服务获取返回数据更容易。

答案 4 :(得分:10)

为什么要重新发明轮子,使用线程和Timer类。

    protected void Application_Start()
    {
        Thread thread = new Thread(new ThreadStart(ThreadFunc));
        thread.IsBackground = true;
        thread.Name = "ThreadFunc";
        thread.Start();
    }

    protected void ThreadFunc()
    {
        System.Timers.Timer t = new System.Timers.Timer();
        t.Elapsed += new System.Timers.ElapsedEventHandler(TimerWorker);
        t.Interval = 10000;
        t.Enabled = true;
        t.AutoReset = true;
        t.Start();
    }

    protected void TimerWorker(object sender, System.Timers.ElapsedEventArgs e)
    {
        //work args
    }

答案 5 :(得分:8)

使用Windows Scheduler运行网页。

为防止恶意用户或搜索引擎蜘蛛运行它,在设置计划任务时,只需使用查询字符串调用网页,即:mypage.aspx?from = scheduledtask

然后在页面加载中,只需使用条件:     if(Request.Querystring [“from”] ==“scheduledtask”)     {     // executetask     }

这样,搜索引擎蜘蛛或恶意用户就无法执行您的计划任务。

答案 6 :(得分:4)

这个图书馆就像一个魅力 http://www.codeproject.com/KB/cs/tsnewlib.aspx

它允许您直接通过.NET代码管理Windows计划任务。

答案 7 :(得分:3)

此外,如果您的应用程序使用SQL SERVER,则可以使用SQL代理来安排任务。这是我们通常放置数据驱动的重复代码(电子邮件提醒,计划维护,清除等)的地方。 SQL代理内置的一个很棒的功能是故障通知选项,可以在关键任务失败时提醒您。

答案 8 :(得分:2)

我不确定你的意思是什么样的预定任务。如果您的意思是“每小时刷新foo.xml”类型的任务,那么请使用Windows计划任务系统。 (“at”命令,或通过控制器。)让它运行一个控制台应用程序或请求一个启动该过程的特殊页面。

编辑:我应该补充一点,这也是让你的IIS应用程序在预定点运行的好方法。因此,假设您希望每30分钟检查一次数据库并向用户发送有关某些数据的提醒,您可以使用计划任务来请求此页面,从而获得IIS处理。

如果您的需求更复杂,您可以考虑创建Windows服务并让它运行循环来执行您需要的任何处理。这也有利于分离出用于扩展或管理目的的代码。不利的一面是,您需要处理Windows服务。

答案 9 :(得分:2)

如果您拥有服务器,则应使用Windows任务计划程序。使用AT /?从命令行查看选项。

否则,从基于Web的环境中,您可能需要做一些令人讨厌的事情,例如设置不同的计算机以定时间隔向某个页面发出请求。

答案 10 :(得分:2)

我在ASP.NET项目中成功使用了Abidar(这里有一些background information)。

此方法的唯一问题是,如果从内存中卸载ASP.NET Web应用程序(即由于使用率低),任务将无法运行。我尝试过的一件事是创建一个任务,每5分钟点击一次Web应用程序,保持活着状态,但这似乎不可靠,所以现在我使用Windows调度程序和基本控制台应用程序来代替。< / p>

理想的解决方案是创建Windows服务,但这可能是不可能的(即,如果您使用的是共享托管环境)。从维护的角度来看,它还使事情变得更容易,以便将内容保存在Web应用程序中。

答案 11 :(得分:1)

这是另一种方式:

1)创建一个“心跳”Web脚本,负责启动任务,如果它们是DUE或过期而无法启动。

2)在某处(最好是在同一个Web服务器上)创建一个计划进程,该进程会触及webscript并强制它以固定间隔运行。 (例如,使用IE或whathaveyou静静地启动热门脚本的Windows计划任务)

任务代码包含在Web脚本中的事实纯粹是为了将代码保持在 Web应用程序代码库中(假设两者都相互依赖) ,这对Web开发人员来说更容易管理。

另一种方法是创建一个可执行服务器脚本/程序,它自己完成所有调度工作,并将可执行文件本身作为计划任务运行。这可以允许Web应用程序和计划任务之间的基本解耦。因此,即使Web应用程序/数据库可能已关闭或无法访问,您仍需要运行计划任务,您应该采用这种方法。

答案 12 :(得分:1)

您可以使用“ThreadPool.RegisterWaitForSingleObject”方法轻松创建一个间隔运行代码的Windows服务。它非常光滑,很容易设置。此方法是一种更简化的方法,然后使用框架中的任何计时器。

请查看以下链接以获取更多信息:

使用Windows服务在.NET中运行定期进程:
http://allen-conway-dotnet.blogspot.com/2009/12/running-periodic-process-in-net-using.html

答案 13 :(得分:0)

我们也使用控制台应用程序。如果您使用Log4net之类的日志工具,则可以正确监视其执行情况。另外,我不确定它们如何比网页更难维护,因为如果设计得当,你可能会在两者之间共享一些相同的代码库。

如果您反对在定时运行这些任务,那么您的网站管理部分中可能会有一个充当队列的网页。用户输入运行任务的请求,然后在MyProcessQueue表上插入空白日期戳记录,并且您的计划任务每​​隔X分钟检查一次MyProcessQueue中的新记录。这样,它只在客户希望它运行时运行。

希望这些建议有所帮助。

答案 14 :(得分:0)

一种选择是设置Windows服务并将其设置为调用您的计划任务。

在winforms中,我使用过Timers,不要认为这在ASP.NET中运行良好

答案 15 :(得分:-1)

.NET的新任务计划程序类库

注意:由于此库已创建,Microsoft已为Windows Vista引入了新的任务调度程序(Task Scheduler 2.0)。该库是Task Scheduler 1.0接口的包装器,它仍可在Vista中使用,并与Windows XP,Windows Server 2003和Windows 2000兼容。

http://www.codeproject.com/KB/cs/tsnewlib.aspx