使用全局asax的简单任务调度

常常对ASP.NET开发人员的要求是定期安排任务。这可以包括站点维护任务,如清理旧文件,在时间表中通过清理通讯。本文检查一个简单的选项,以便管理如此如此,而无需配置外部工具,并讨论几个替代方案。

如果您可以访问Web服务器本身,则可能会使用WMI来安排任务(http://msdn.microsoft.com/en-us/library/aa394601(VS.85).aspx)或者您甚至可能会考虑使用SQL Server代理在计划上运行作业(http://msdn.microsoft.com/en-us/library/ms191439.aspx)。但是,如果您使用的是共享托管计划,或者SQL Server代理不可用,则需要另一种方法来管理任务。 Global.asax文件使您可以访问您可以使用的定期事件来管理。感兴趣的两个主要事件是application_start(),它在制作对应用程序的第一个请求时发生 - 通常由于首先部署的站点,或者由于任何原因重新启动应用程序进程(服务器关闭,重新编译等)每当新访客在您的网站上的新访客降落时,会遇到的session_start()。看 ASP.NET应用程序生命周期概述IIS 5.0和6.0 for more details.

如果您的Web应用程序不包含一个名为global.asax的文件,则易于添加一个文件。右键单击解决方案资源管理器中的项目名称,然后选择添加新项目

从出现的对话框,选择全局应用程序类

您的IDE应该以此开放Global.asax,您应该在a中看到自动化的代码<script runat="server">堵塞。五个事件处理程序已准备好并等待封面应用程序启动,应用端,应用程序错误,会话开始和会话结束。出于此插图的目的,我将假设常规任务将是一个检查文件夹的文件夹,用于多个日历,并删除它们。一世'M还将假设Web应用程序获得足够的访问者,该访问者将经常发射Session_start(),以便为触发点提供目的。我们需要一些将迭代文件夹中文件的代码,并检查其创建的日期。如果该日期超过24小时,则该文件已删除。我们不'当每个访客在网站上的土地上时,要在网站上运行此代码。每天一次都会做一次。因此,需要有一些方法来检查最后一个ran的任务。

在Global.asax的顶部,我们将添加一个可变的变量,该变量将在上次运行的任务时指示的DateTime,并将其初始化到应用程序启动时的当前时间:

private static DateTime whenTaskLastRan;

void Application_Start(object sender, EventArgs e)
{
    whenTaskLastRan = DateTime.Now;
}

我们已经决定在session_start()中运行任务。所以我们在那里添加一个方法:

void Session_Start(object sender, EventArgs e)
{
  DoTask();
}

在Global.asax的底部,我们将方法dotask()添加了它的实现代码:

static void DoTask()
{
  var oneDayAgo = DateTime.Now.AddDays(-1);
  if (whenTaskLastRan.IsOlderThan(oneDayAgo))
  {
    var path = HttpContext.Current.Server.MapPath("Uploads");
    var folder = new DirectoryInfo(path);
    FileInfo[] files = folder.GetFiles();
    foreach (var file in files)
    {
      if(file.CreationTime.IsOlderThan(oneDayAgo))
      {
        File.Delete(path + file.Name);
      }
    }
    whenTaskLastRan = DateTime.Now;
  }
}

DateTime - Onedayago在现在或一天前设有24小时。将应用程序变量设置为Application_start()事件,与Onedayago进行比较,看看较旧的。您可能会在用于执行此操作的方法中提高眼睫报:Isolderthan()。它's视图这样的扩展方法:

public static bool IsOlderThan(this DateTime dt1, DateTime dt2)
{
  return dt1 < dt2;
}

本身就是'做很多 - 它只是返回一个BOOL,指示一个DATETIME是否在另一个时刻。但是,它的使用使得代码更可读。

备择方案

在不使用第三方应用程序的情况下,我已经看到了一个替代方案,我已经看到了在不使用第三方应用程序的情况下调度任务,这是使用缓存对象的使用。这里详述了: http://www.codeproject.com/KB/aspnet/ASPNETService.aspx。对于需要更频繁地运行的任务,参观者在您的网站上降落,这可能是一个更好的选择。但是,对我来说似乎有点矫枉过正。我可以'想到一个真正的世界场景,其中一个Web应用程序真正需要比游客在网站上的游客更频繁地执行任务。它可能有用的一个地方是在特定时间执行任务。如果您需要精确地控制时间(以任何方式达到大约2分钟),那么缓存方法会更好,希望游客在正确的时间内降落在您的网站上。当然,这取决于您的网站和流量水平。

另一种替代方案是将Dotask()的代码放在主页的Page_load事件中。这将确保每次任何人降落在该页面时都会运行。在我的网站的情况下,主页是最少访问的页面之一。您可以通过创建从页面继承的基础来确保它为每个页面请求发出触发,然后从Basepage中的所有网络表单子类。 DOTASK()可以放在基础上的pre_init()事件中。最终选项是坚持使用Global.asax,并在application_beginrequest()中放入dotask()。每次在您的网站上请求页面时也会被解雇。

本文研究了许多用于自动化任务的选项,而无需在Web服务器上配置第三方工具。您选择的选项将取决于任务的频率,您可以在任务的时间内接受的公差级别,以及您网站获取的访客数量。