今天我们构建了一个控制台应用程序,用于运行ASP.NET网站的计划任务。但我认为这种方法有点容易出错且难以维护。如何执行计划任务(在Windows / IIS / ASP.NET环境中)
更新:
任务示例:
答案 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)
我将一些任务关键任务设置为计划的控制台应用程序,并发现它们很难维护。我创建了一个带有'heartbeat'的Windows服务,可以每隔几分钟检查一次我的数据库中的计划。它运作得很好。
话虽如此,我仍然使用预定的控制台应用程序来执行大多数非关键维护任务。如果没有损坏,请不要修理它。
答案 3 :(得分:17)
我发现这对所有参与者都很容易:
使用此方法,您的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兼容。