运行计划任务的最佳方式

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

更新:

任务示例:

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

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

另一种便捷的方法是使用Pingdom等监控服务。 将他们的http检查指向运行你的服务代码的页面。 让页面返回结果,然后可以用它来触发Pingdom在事情不正确时发送警报消息。

Jeff Atwood的Stackoverflow技术是我遇到的最简单的方法。 它依靠“caching项删除”callback机制构build到ASP.NET的caching系统中

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

也检查出Quartz.NET

创build一个自定义的Windows服务 。

我将一些任务关键任务设置为预定的控制台应用程序,并发现难以维护。 我创build了一个带有“心跳”的Windows服务,每隔几分钟就会检查我的数据库中的时间表。 它的工作得很好。

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

我发现这对所有参与者都很简单:

  • 创build一个Web服务方法,如DoSuchAndSuchProcess
  • 创build一个调用此webmethod的控制台应用程序。
  • 调度任务计划程序中的控制台应用程序。

使用这种方法,所有的业务逻辑都包含在您的Web应用程序中,但您拥有Windows任务pipe理器或任何其他商业任务pipe理器的可靠性,可以将其启动并logging任何返回信息,如执行报告。 使用Web服务而不是张贴到页面有一个优点,因为从Web服务获取返回数据更容易。

为什么重新发明轮子,使用线程和定时器类。

  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 } 

使用Windows计划程序来运行网页。

为了防止恶意用户或search引擎蜘蛛运行它,当你设置计划任务时,只需使用查询string调用网页,即:mypage.aspx?from = scheduledtask

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

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

这个库的作品像一个魅力http://www.codeproject.com/KB/cs/tsnewlib.aspx

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

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

编辑:我应该补充说,这是一个好方法让您的IIS应用程序也在计划点运行。 所以假设你想每隔30分钟检查你的数据库,并通过电子邮件向用户发送关于某些数据的提醒,你可以使用计划任务来请求这个页面,从而获得IIS处理的东西。

如果你的需求比较复杂,你可以考虑创build一个Windows服务并让它运行一个循环来做你需要的任何处理。 这也有利于将缩放或pipe理目的的代码分离出来。 缺点是,你需要处理Windows服务。

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

否则,从一个基于Web的环境中,你可能不得不做一些讨厌的事情,比如设置一个不同的机器,以定时的间隔向某个页面发出请求。

我在ASP.NET项目中成功地使用了Abidar (这里有一些背景信息 )。

这种方法唯一的问题是,如果ASP.NET Web应用程序从内存中卸载(即由于使用率低),任务将不会运行。 我尝试的一件事是创build一个任务,每隔5分钟打一次Web应用程序,保持活跃状态​​,但这似乎并不可靠,所以现在我正在使用Windows调度程序和基本控制台应用程序来执行此操作。

理想的解决scheme是创build一个Windows服务,虽然这可能是不可能的(即如果你使用的是共享主机环境)。 从维护的angular度来看,它也使事情变得更容易,以保持在Web应用程序中的东西。

此外,如果您的应用程序使用SQL SERVER,则可以使用SQL代理来安排您的任务。 这是我们通常把重新发生的数据驱动的代码(电子邮件提醒,定期维护,清除等)。 SQL代理内置的一个很好的function是故障通知选项,如果关键任务失败,可以提醒您。

这是另一种方式:

1)创build一个“心跳”web脚本,负责启动任务,如果他们是DUE或逾期将启动。

2)创build一个预定的进程(最好在同一个Web服务器上)击中web脚本,并强制它定期运行。 (例如,使用IE或Whathaveyou悄悄启动热启动脚本的Windows计划任务)

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

另一种方法是创build一个可执行的服务器脚本/程序,它可以使所有的日程安排自行工作,并将可执行文件本身作为计划任务运行。 这可以允许Web应用程序和计划任务之间的基本解耦。 因此,如果您甚至需要计划的任务运行,即使Web应用程序/数据库可能closures或无法访问,您也应该采用这种方法。

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

看看下面的链接了解更多信息:

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

我们也使用控制台程序。 如果使用Log4net等日志工具,则可以正确监视其执行情况。 此外,我不确定他们比网页更难以维护,因为如果devise正确,您可能会在两者之间共享相同的代码库。

如果您反对让这些任务定时运行,那么您的网站的pipe理部分中可能会有一个网页作为队列。 用户放入请求来运行任务,它依次在MyProcessQueue表上插入一个空白的date戳logging,并且您的计划任务是每隔X分钟检查一次MyProcessQueue中的新logging。 这样,只有当客户希望运行时才会运行。

希望这些build议有帮助。

一种select是build立一个Windows服务,并打电话给你的计划任务。

在winforms我用定时器把不认为这将在ASP.NET中工作

.NET的新任务调度程序类库

注意:由于此库已创build,因此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