Asp.Net(C#)自动执行计划任务的程序实例分析

系统 2012 0

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

      
        1
      
      
        public
      
      
        interface
      
      
         ISchedulerJob

      
      
        2
      
      
            {

      
      
        3
      
      
        void
      
      
         Execute();

      
      
        4
      
           }
    

  如前所述,我们的例子是实现往文件写如字符日期,下面就是实现这一任务的方法:

      
         1
      
      
        public
      
      
        class
      
      
         SampleJob : ISchedulerJob 

      
      
         2
      
      
        { 

      
      
         3
      
      
        public
      
      
        void
      
      
         Execute() 

      
      
         4
      
      
        { 

      
      
         5
      
      
        //
      
      
        文件保存的物理路径,CSTest为虚拟目录名称,F:\Inetpub\wwwroot\CSTest为物理路径 
      
      
         6
      
      
        string
      
       p = 
      
        @"C:\Users\Jack\Desktop\AutoRun\AutoRun
      
      
        "
      
      
        ; 

      
      
         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
      
       } 
    

  接下来,我们建立一个配置对象,告诉调度引擎执行什么任务和执行的时间间隔。

      
         1
      
      
        public
      
      
        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
      
      
        下面就是调度引擎,定时执行配置对象的任务 

      
      
        19
      
      
        20
      
      
        public
      
      
        class
      
      
         Scheduler 

      
      
        21
      
      
        { 

      
      
        22
      
      
        private
      
       SchedulerConfiguration configuration = 
      
        null
      
      
        ; 

      
      
        23
      
      
        24
      
      
        public
      
      
         Scheduler(SchedulerConfiguration config) 

      
      
        25
      
      
        { 

      
      
        26
      
       configuration =
      
         config; 

      
      
        27
      
      
        } 

      
      
        28
      
      
        29
      
      
        public
      
      
        void
      
      
         Start() 

      
      
        30
      
      
        { 

      
      
        31
      
      
        while
      
      (
      
        true
      
      
        ) 

      
      
        32
      
      
        { 

      
      
        33
      
      
        //
      
      
        执行每一个任务 
      
      
        34
      
      
        foreach
      
      (ISchedulerJob job 
      
        in
      
      
         configuration.Jobs) 

      
      
        35
      
      
        { 

      
      
        36
      
       ThreadStart myThreadDelegate = 
      
        new
      
      
         ThreadStart(job.Execute); 

      
      
        37
      
       Thread myThread = 
      
        new
      
      
         Thread(myThreadDelegate); 

      
      
        38
      
      
        myThread.Start(); 

      
      
        39
      
      
        Thread.Sleep(configuration.SleepInterval); 

      
      
        40
      
      
        } 

      
      
        41
      
      
        } 

      
      
        42
      
      
        } 

      
      
        43
      
       } 
    

  所有的准备工作已经完成,下面就是激活引擎的工作了。为了让我们的任务计划执行,我们在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
      
       SchedulerConfiguration config = 
      
        new
      
       SchedulerConfiguration(
      
        1000
      
      *
      
        3
      
      
        ); 

      
      
         5
      
       config.Jobs.Add(
      
        new
      
      
         SampleJob()); 

      
      
         6
      
       Scheduler scheduler = 
      
        new
      
      
         Scheduler(config); 

      
      
         7
      
       System.Threading.ThreadStart myThreadStart = 
      
        new
      
      
         System.Threading.ThreadStart(scheduler.Start); 

      
      
         8
      
       System.Threading.Thread schedulerThread = 
      
        new
      
      
         System.Threading.Thread(myThreadStart); 

      
      
         9
      
      
        schedulerThread.Start(); 

      
      
        10
      
       } 
    

  最后还需要在程序退出时进行销毁:

      
        1
      
      
        protected
      
      
        void
      
      
         Application_End(Object sender, EventArgs e) 

      
      
        2
      
      
        { 

      
      
        3
      
      
        if
      
       (
      
        null
      
       !=
      
         schedulerThread) 

      
      
        4
      
      
        { 

      
      
        5
      
      
        schedulerThread.Abort(); 

      
      
        6
      
      
        } 

      
      
        7
      
       } 
    

  好了,在VS.NET里建立一个C#的Web应用程序工程,建立TaskScheduler.cs类,并修改相应的Global.asax.cs文件。为了能看到效果,我们再建立一个表单WebForm1.aspx,定时刷新来检查我们所记录的数据:

      
         1
      
       <%@ Page language=
      
        "
      
      
        c#
      
      
        "
      
       Codebehind=
      
        "
      
      
        WebForm1.aspx.cs
      
      
        "
      
       AutoEventWireup=
      
        "
      
      
        false
      
      
        "
      
      
         2
      
       Inherits=
      
        "
      
      
        CSTest.WebForm1
      
      
        "
      
       %> 

      
         3
      
       <!DOCTYPE HTML PUBLIC 
      
        "
      
      
        -//W3C//DTD HTML 4.0 Transitional//EN
      
      
        "
      
       > 

      
         4
      
       <HTML> 

      
         5
      
       <HEAD> 

      
         6
      
       <title>在Web应用程序中执行计划任务的例子</title> 

      
         7
      
       <meta http-equiv=
      
        "
      
      
        refresh
      
      
        "
      
       content=
      
        "
      
      
        10
      
      
        "
      
      > 

      
         8
      
       <meta name=
      
        "
      
      
        GENERATOR
      
      
        "
      
       Content=
      
        "
      
      
        Microsoft Visual Studio 7.0
      
      
        "
      
      > 

      
         9
      
       <meta name=
      
        "
      
      
        CODE_LANGUAGE
      
      
        "
      
       Content=
      
        "
      
      
        C#
      
      
        "
      
      > 

      
        10
      
       <meta name=
      
        "
      
      
        vs_defaultClientScript
      
      
        "
      
       content=
      
        "
      
      
        JavaScript
      
      
        "
      
      > 

      
        11
      
       <meta name=
      
        "
      
      
        vs_targetSchema
      
      
        "
      
       content=
      
        "
      
      
        http://schemas.microsoft.com/intellisense/ie5
      
      
        "
      
      > 

      
        12
      
       </HEAD> 

      
        13
      
       <body MS_POSITIONING=
      
        "
      
      
        GridLayout
      
      
        "
      
      > 

      
        14
      
       <form id=
      
        "
      
      
        Form1
      
      
        "
      
       method=
      
        "
      
      
        post
      
      
        "
      
       runat=
      
        "
      
      
        server
      
      
        "
      
      > 

      
        15
      
       <iframe style=
      
        "
      
      
        width:100%;height:100%
      
      
        "
      
       src=
      
        "
      
      
        SchedulerJob/SchedulerJob.txt
      
      
        "
      
      ></iframe> 

      
        16
      
       </form> 

      
        17
      
       </body> 

      
        18
      
       </HTML>
      
      
    

  对工程进行编译并运行,就可以看到结果了,结果如下:

计划任务测试开始:
2003-13-10 11:08:15
2003-13-10 11:08:18
2003-13-10 11:08:21
2003-13-10 11:08:24
2003-13-10 11:08:27
2003-13-10 11:08:30

  需要说明的是,以上只是在Web应用程序中执行计划任务的简单例子,对于多个任务来说,需要在不同的线程内进行工作,对计划的安排也是很简单的,实际还需要站点堵塞,当机的情况。另外这里也没有进行错误的处理等工作,相信大家会写出更加完美的代码的。

点击下载源码: http://files.cnblogs.com/zhaoxuntao/AutoRun.zip


资源回收,当web没有人访问的时候,定时器会回收停掉
不知道在 Application_End 时自动访问一次有用么,我这前测试了几天这个方法都可以行。
void Application_End(object sender, EventArgs e)
{
///在应用程序关闭时运行的代码
webSocket.Stop();
Thread.Sleep(15000);
try
{
string url = " http://127.0.0.1/404.aspx?mater=" + DateTime.Now.Ticks;
HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
using (HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse())
{
Stream resStream = response.GetResponseStream();
}
}
catch (Exception ex)
{
//异常时,等15s,再访问一次。
Thread.Sleep(15000);
string url = " http://127.0.0.1/404.aspx?mater=" + DateTime.Now.Ticks;
HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
using (HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse())
{
Stream resStream = response.GetResponseStream();
}

Hangjing.AppLog.AppLog.Error("Application_End:" + ex);
}

}


Asp.Net(C#)自动执行计划任务的程序实例分析


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论