在Web应用程序中执行计划任务(多线程)

本文介绍了一种在Web应用程序中实现计划任务的简便方法,通过在Application_Start和Application_End事件中启动和停止任务,无需额外配置即可定时执行如文件写入等操作。

在 业务复杂的应用程序中,有时候会要求一个或者多个任务在一定的时间或者一定的时间间隔内计划进行,比如定时备份或同步数据库,定时发送电子邮件等,我们称 之为计划任务。实现计划任务的方法也有很多,可以采用SQLAgent执行存储过程来实现,也可以采用Windows任务调度程序来实现,也可以使用 Windows服务来完成我们的计划任务,这些方法都是很好的解决方案。但是,对于Web应用程序来说,这些方法实现起来并不是很简单的,主机服务提供商 或者不能直接提供这样的服务,或者需要你支付许多额外的费用。 本文就介绍一个直接在Web应用程序中使用的简单的方法,这个方法不需要任何额外的配置即可轻松实现。

由于ASP.NET站点是作为Web应用程序运行的,它并不受线程的限制,因此我们可以非常方便地在Application_Start Application_End事件中建立和销毁一个计划任务。下面就简单介绍一下在Web站点实现计划任务的方法。我们的例子是定时往文件里添加信息, 作为例子,这里把当前的时间定时地写入文件中。

一个计划任务的工作单元称之为一个任务(Job),下面的代码描述了对所有任务都可以被调度引擎计划执行的一个通用的接口,这里的每个任务实现了Execute方法,供调度引擎进行调用:

         public interface ISchedulerJob

         {

          void Execute();

         }

 

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

         public class SampleJob : ISchedulerJob

         {

          public void Execute()

          {

           //文件保存的物理路径,CSTest为虚拟目录名称,F:/Inetpub/wwwroot/CSTest为物理路径

           string p = @"F:/Inetpub/wwwroot/CSTest";

           //我们在虚拟目录的根目录下建立SchedulerJob文件夹,并设置权限为匿名可修改,

           //SchedulerJob.txt就是我们所写的文件

           string FILE_NAME = p+ "//SchedulerJob//SchedulerJob.txt";

           //取得当前服务器时间,并转换成字符串

           string c = System.DateTime.Now.ToString("yyyy-mm-dd hh:MM:ss");

           //标记是否是新建文件的标量

           bool flag = false;

           //如果文件不存在,就新建该文件

           if (!File.Exists(FILE_NAME))

           {

            flag = true;

            StreamWriter sr = File.CreateText(FILE_NAME);

            sr.Close();

           }

           //向文件写入内容

           StreamWriter x = new StreamWriter(FILE_NAME,true,System.Text.Encoding.Default);

           if(flag) x.Write("计划任务测试开始:");

           x.Write("/r/n"+c);

           x.Close();

          }

         }

 

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

         public class SchedulerConfiguration

         {

          //时间间隔

          private int sleepInterval;

          //任务列表

          private ArrayList jobs = new ArrayList();

 

          public int SleepInterval { get { return sleepInterval; } }

          public ArrayList Jobs { get { return jobs; } }

 

          //调度配置类的构造函数

          public SchedulerConfiguration(int newSleepInterval)

          {

           sleepInterval = newSleepInterval;

          }

         }

 

下面就是调度引擎,定时执行配置对象的任务

         public class Scheduler

         {

          private SchedulerConfiguration configuration = null;

 

          public Scheduler(SchedulerConfiguration config)

          {

           configuration = config;

          }

 

          public void Start()

          {

           while(true)

           {

            //执行每一个任务

            foreach(ISchedulerJob job in configuration.Jobs)

            {

             ThreadStart myThreadDelegate = new ThreadStart(job.Execute);

             Thread myThread = new Thread(myThreadDelegate);

             myThread.Start();

             Thread.Sleep(configuration.SleepInterval);

            }

           }

          }

         }

 

所有的准备工作已经完成,下面就是激活引擎的工作了。为了让我们的任务计划执行,我们在Global.asax.cs文件里的 Applicatio_StartApplication_End里进行建立和销毁工作,首先建立一个调度进程运行的线程,我们这里的运行间隔时间为3 秒钟。

  public System.Threading.Thread schedulerThread = null;

  protected void Application_Start(Object sender, EventArgs e)

  {

    SchedulerConfiguration config =  new SchedulerConfiguration(1000*3);

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

    Scheduler scheduler = new Scheduler(config);

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

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

    schedulerThread.Start();

  }

 

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

  protected void Application_End(Object sender, EventArgs e)

  {

    if (null != schedulerThread)

    {

      schedulerThread.Abort();

    }

  }

 

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

        <%&#64; Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false"

         Inherits="CSTest.WebForm1" %>

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

        <HTML>

          <HEAD>

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

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

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

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

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

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

          </HEAD>

          <body MS_POSITIONING="GridLayout">

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

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

            </form>

          </body>

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

/// 系统开启事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Application_Start(Object sender, EventArgs e)
{
      //创建一个新的Timer实例
    System.Timers.Timer sysTimer = new System.Timers.Timer();      
    //sysTimer_Elapsed指定为计时器的 Elapsed 事件处理程序
    sysTimer.Elapsed += new System.Timers.ElapsedEventHandler(sysTimer_Elapsed);
      //一个小时执行一次,此单位为毫秒
    sysTimer.Interval = 60*60*1000;
    sysTimer.AutoReset = true;
    sysTimer.Enabled = true;
}


/// <summary>
///
定时器事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void sysTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
  //为了实现在12点开始执行,要做一些判断工作
    if(DateTime.Now.Hour = 0)
    {
        //
开始执行预定任务
    }
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值