在业务复杂的应用程序中,有时候会要求一个或者多个任务在一定的时间或者一定的时间间隔内计划进行,比如定时备份或同步数据库,定时发送电子邮件等,我们称之为计划任务。实现计划任务的方法也有很多,可以采用SQLAgent执行存储过程来实现,也可以采用Windows任务调度程序来实现,也可以使用Windows服务来完成我们的计划任务,这些方法都是很好的解决方案。但是,对于Web应用程序来说,这些方法实现起来并不是很简单的,主机服务提供商或者不能直接提供这样的服务,或者需要你支付许多额外的费用。   本文就介绍一个直接在Web应用程序中使用的简单的方法,这个方法不需要任何额外的配置即可轻松实现。  
   
  由于ASP.NET站点是作为Web应用程序运行的,它并不受线程的限制,因此我们可以非常方便地在Application_Start和Application_End事件中建立和销毁一个计划任务。下面就简单介绍一下在Web站点实现计划任务的方法。我们的例子是定时往文件里添加信息,作为例子,这里把当前的时间定时地写入文件中。  
   
  一个计划任务的工作单元称之为一个任务(Job),下面的代码描述了对所有任务都可以被调度引擎计划执行的一个通用的接口,这里的每个任务实现了Execute方法,供调度引擎进行调用:   
    

1 public   interface   ISchedulerJob   
2    {   
3      void   Execute();   
4    }
   
  如前所述,我们的例子是实现往文件写如字符日期,下面就是实现这一任务的方法:   
    

 1public   class   SampleJob   :   ISchedulerJob   
 2    {   
 3      public   void   Execute()   
 4      {   
 5        //文件保存的物理路径,CSTest为虚拟目录名称,F:\Inetpub\wwwroot\CSTest为物理路径   
 6        string   p   =   @"F:\Inetpub\wwwroot\CSTest";   
 7        //我们在虚拟目录的根目录下建立SchedulerJob文件夹,并设置权限为匿名可修改,   
 8        //SchedulerJob.txt就是我们所写的文件   
 9        string   FILE_NAME   =   p+   "\\SchedulerJob\\SchedulerJob.txt";   
10        //取得当前服务器时间,并转换成字符串   
11        string   c   =   System.DateTime.Now.ToString("yyyy-mm-dd   hh:MM:ss");   
12        //标记是否是新建文件的标量   
13        bool   flag   =   false;   
14        //如果文件不存在,就新建该文件   
15        if   (!File.Exists(FILE_NAME))   
16        {   
17          flag   =   true;   
18          StreamWriter   sr   =   File.CreateText(FILE_NAME);   
19          sr.Close();   
20        }
   
21        //向文件写入内容   
22        StreamWriter   x   =   new   StreamWriter(FILE_NAME,true,System.Text.Encoding.Default);   
23        if(flag)   x.Write("计划任务测试开始:");   
24        x.Write("\r\n"+c);   
25        x.Close();   
26      }
   
27    }
   
28
    
  接下来,我们建立一个配置对象,告诉调度引擎执行什么任务和执行的时间间隔。   
   

 1public   class   SchedulerConfiguration   
 2    {   
 3      //时间间隔   
 4      private   int   sleepInterval;   
 5      //任务列表   
 6      private   ArrayList   jobs   =   new   ArrayList();   
 7    
 8      public   int   SleepInterval   {   get   {   return   sleepInterval;   }   }   
 9      public   ArrayList   Jobs   {   get   {   return   jobs;   }   }   
10    
11      //调度配置类的构造函数   
12      public   SchedulerConfiguration(int   newSleepInterval)   
13      {   
14        sleepInterval   =   newSleepInterval;   
15      }
   
16    }
   
17    
18
 
  下面就是调度引擎,定时执行配置对象的任务   
   

 1 public   class   Scheduler   
 2    {   
 3      private   SchedulerConfiguration   configuration   =   null;   
 4    
 5      public   Scheduler(SchedulerConfiguration   config)   
 6      {   
 7        configuration   =   config;   
 8      }
   
 9    
10      public   void   Start()   
11      {   
12        while(true)   
13        {   
14          //执行每一个任务   
15          foreach(ISchedulerJob   job   in   configuration.Jobs)   
16          {   
17            ThreadStart   myThreadDelegate   =   new   ThreadStart(job.Execute);   
18            Thread   myThread   =   new   Thread(myThreadDelegate);   
19            myThread.Start();   
20            Thread.Sleep(configuration.SleepInterval);   
21          }
   
22        }
   
23      }
   
24    }
    
  所有的准备工作已经完成,下面就是激活引擎的工作了。为了让我们的任务计划执行,我们在Global.asax.cs文件里的Applicatio_Start和Application_End里进行建立和销毁工作,首先建立一个调度进程运行的线程,我们这里的运行间隔时间为3秒钟。   
    

 1 public   System.Threading.Thread   schedulerThread   =   null;   
 2      protected   void   Application_Start(Object   sender,   EventArgs   e)   
 3      {   
 4