今天,我们构建了一个控制台应用程序,用于为我们的 ASP.NET 网站运行计划任务。但我认为这种方法有点容易出错并且难以维护。你如何执行你的计划任务(在 windows/IIS/ASP.NET 环境中)
更新:
任务示例:
- 从数据库中的电子邮件队列发送电子邮件
- 从数据库中删除过时的对象
- 从 Google AdWords 检索统计信息并在数据库中填写表格。
今天,我们构建了一个控制台应用程序,用于为我们的 ASP.NET 网站运行计划任务。但我认为这种方法有点容易出错并且难以维护。你如何执行你的计划任务(在 windows/IIS/ASP.NET 环境中)
更新:
任务示例:
Jeff Atwood 为 Stackoverflow 提供的这项技术是我遇到的最简单的方法。它依赖于 ASP.NET 缓存系统中内置的“缓存项已删除”回调机制
更新: Stackoverflow 已经超越了这种方法。它仅在网站运行时有效,但它是一种非常简单的技术,对许多人都很有用。
另请查看Quartz.NET
我所有的网站任务(需要安排)都保存在网站内,并从一个特殊页面调用。然后我编写了一个简单的 Windows 服务,它每隔一段时间就会调用这个页面。一旦页面运行,它就会返回一个值。如果我知道还有更多工作要做,我会立即再次运行该页面,否则我将在稍后运行它。这对我来说非常有效,并将我的所有任务逻辑都保留在 Web 代码中。在编写简单的 Windows 服务之前,我使用 Windows 调度程序每 x 分钟调用一次页面。
运行它的另一种便捷方法是使用Pingdom 之类的监控服务。将他们的 http 检查指向运行您的服务代码的页面。让页面返回结果,然后可用于触发 Pingdom 在出现问题时发送警报消息。
我将一些关键任务任务设置为计划的控制台应用程序,但发现它们难以维护。我创建了一个带有“心跳”的 Windows 服务,它会每隔几分钟检查一次我的数据库中的时间表。效果非常好。
话虽如此,我仍然使用计划的控制台应用程序来完成大多数非关键维护任务。如果它没有坏,就不要修理它。
我发现这对所有相关人员来说都很容易:
使用这种方法,所有业务逻辑都包含在您的 Web 应用程序中,但您可以使用 Windows 任务管理器或任何其他商业任务管理器来启动它并记录任何返回信息,例如执行报告。使用 Web 服务而不是发布到页面有一点优势,因为从 Web 服务获取返回数据更容易。
为什么要重新发明轮子,使用 Threading 和 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
}
使用 Windows 调度程序运行网页。
为了防止恶意用户或搜索引擎蜘蛛运行它,当您设置计划任务时,只需使用查询字符串调用网页,即:mypage.aspx?from=scheduledtask
然后在页面加载中,只需使用一个条件: if (Request.Querystring["from"] == "scheduledtask") { //executetask }
这样,任何搜索引擎蜘蛛或恶意用户都无法执行您的计划任务。
这个库就像一个魅力 http://www.codeproject.com/KB/cs/tsnewlib.aspx
它允许您通过 .NET 代码直接管理 Windows 计划任务。
此外,如果您的应用程序使用 SQL SERVER,您可以使用 SQL 代理来安排您的任务。这是我们通常放置重复出现的数据驱动代码(电子邮件提醒、计划维护、清除等)的地方。SQL 代理内置的一个很棒的功能是失败通知选项,它可以在关键任务失败时提醒您。
我不确定您的意思是哪种计划任务。如果您的意思是“每小时刷新 foo.xml”类型的任务,请使用 Windows 计划任务系统。(“at”命令,或通过控制器。)让它运行控制台应用程序或请求启动该过程的特殊页面。
编辑:我应该补充一点,这也是让您的 IIS 应用程序在预定点运行的好方法。因此,假设您想每 30 分钟检查一次数据库并向用户发送有关某些数据的电子邮件提醒,您可以使用计划任务来请求此页面,从而让 IIS 处理事物。
如果您的需求更复杂,您可能会考虑创建一个 Windows 服务并让它运行一个循环来执行您需要的任何处理。这还具有分离代码以进行扩展或管理目的的好处。不利的一面是,您需要处理 Windows 服务。
如果您拥有服务器,则应使用 Windows 任务调度程序。使用 AT/? 从命令行查看选项。
否则,在基于 Web 的环境中,您可能不得不做一些令人讨厌的事情,例如设置另一台机器以按时间间隔向某个页面发出请求。
我已经在一个 ASP.NET 项目中成功使用了Abidar (这里有一些背景信息)。
此方法的唯一问题是,如果 ASP.NET Web 应用程序从内存中卸载(即由于使用率低),任务将无法运行。我尝试过的一件事是创建一个任务,每 5 分钟访问一次 Web 应用程序,使其保持活动状态,但这似乎不能可靠地工作,所以现在我使用 Windows 调度程序和基本控制台应用程序来代替它。
理想的解决方案是创建 Windows 服务,尽管这可能是不可能的(即,如果您使用的是共享托管环境)。从维护的角度来看,它还使事情变得更容易,以便将内容保留在 Web 应用程序中。
这是另一种方式:
1) 创建一个“心跳”web 脚本,负责在任务到期或逾期启动时启动它们。
2)在某处(最好在同一Web服务器上)创建一个预定进程,该进程命中webscript并强制它定期运行。(例如,使用 IE 或 whathaveyou 悄悄启动 heatbeat 脚本的 windows 调度任务)
任务代码包含在 Web 脚本中的事实纯粹是为了将代码保留在Web 应用程序代码库中(假设两者相互依赖),这对于 Web 开发人员来说更容易管理.
另一种方法是创建一个可执行的服务器脚本/程序,它自己完成所有计划工作,并将可执行文件本身作为计划任务运行。这可以允许 Web 应用程序和计划任务之间的基本解耦。因此,如果您需要在 Web 应用程序/数据库可能已关闭或无法访问的情况下运行计划任务,您应该采用这种方法。
您可以使用“ThreadPool.RegisterWaitForSingleObject”方法轻松创建间隔运行代码的 Windows 服务。它真的很流畅,很容易设置。与使用框架中的任何计时器相比,此方法是一种更简化的方法。
请查看以下链接以获取更多信息:
使用 Windows 服务在 .NET 中运行定期进程:http:
//allen-conway-dotnet.blogspot.com/2009/12/running-periodic-process-in-net-using.html
我们也使用控制台应用程序。如果您使用 Log4net 等日志工具,您可以正确监控它们的执行。此外,我不确定它们如何比网页更难维护,因为如果设计得当,您可能会在两者之间共享一些相同的代码库。
如果您反对让这些任务定时运行,您可以在网站的管理部分中有一个网页作为队列。用户提出运行任务的请求,然后它会在 MyProcessQueue 表中插入一个空白的时间戳记录,并且您的计划任务每 X 分钟检查一次 MyProcessQueue 中的新记录。这样,它只在客户希望它运行时运行。
希望这些建议有所帮助。
一种选择是设置 Windows 服务并让它调用您的计划任务。
在我使用过的 Winforms 中,Timers put 认为这在 ASP.NET 中效果不佳
.NET 的新任务计划程序类库
注意:自创建此库以来,Microsoft 为 Windows Vista 引入了新的任务计划程序(Task Scheduler 2.0)。该库是 Task Scheduler 1.0 接口的包装器,该接口在 Vista 中仍然可用,并且与 Windows XP、Windows Server 2003 和 Windows 2000 兼容。