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

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

 

 
在业务复杂的应用程序中,有时候会要求一个或者多个任务在一定的时间或者一定的时间间隔内计划进行,比如定时备份或同步数据库,定时发送电子邮件等,我们称之为计划任务。实现计划任务的方法也有很多,可以采用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:InetpubwwwrootCSTest为物理路径
       string p = @"F:InetpubwwwrootCSTest";
       //我们在虚拟目录的根目录下建立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(" "+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_Start和Application_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,定时刷新来检查我们所记录的数据:

    
<%...@ 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">
      
</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应用程序中执行计划任务的简单例子,对于多个任务来说,需要在不同的线程内进行工作,对计划的安排也是很简单的,实际还需要站点堵塞,当机的情况。另外这里也没有进行错误的处理等工作,相信大家会写出更加完美的代码的。
 
C# Timer 每日定时执行任务 应用场景 公司旧项目需修改原有的数据备份功能,原功能为在实时数据入库后进行数据备份,备份方法为将实时数据转化为二进制数组后按照当天日期进行入库,之后每次有实时数据入库都需要将历史数据表中的二进制数据字段查询后在尾部添加新二进制数据,再更新入库。然而这个系统为数据监控系统,每秒都会有将近百条记录入库,所以上述原功能会导致运行迟缓,消耗资源。 现改为每日零时进行一次性的数据备份。 定时任务可以有两种方式实现: 第一种是使用定时间隔为一秒的计时器System.Timers.Timer,一直循环判断当前时间是. 阅读详情

相关推荐

C# 定时任务实现全攻略:从简单到复杂的定时任务解决方案

简单任务:如果只是需要基于固定时间间隔执行任务,可以使用或。异步任务:如果在异步环境中,需要非阻塞的定时任务,可以使用Task.Delay。复杂调度:对于需要复杂调度、CRON 表达式或任务优先级的场景,推荐使用Quartz.NET。每种方法都有其适用的场景,掌握这些定时任务实现方式可以让你在不同的项目中高效地处理周期性任务,提升代码的可维护性和可靠性。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 3025

c#实现每隔一段时间执行代码(多线程)

总结以下三种方法,实现c#每隔一段时间执行代码: 方法一:调用线程执行方法,在方法中实现死循环,每个循环Sleep设定时间; 方法二:使用System.Timers.Timer类; 方法三:使用System.Threading.Timer; 1 2 3 4 5 6 7 8 9 10 11

luckypeng的专栏 1万+

定时任务实现(C#原创)

定时任务实现(C#原创)定时任务实现(C#原创)定时任务实现(C#原创)

C# 定时器的三种实现方式:Timer

Timer实现 1.System.Timers.Timer: 这个Timer是使用线程池中的线程去执行任务的,,既然是使用线程池里的线程,就必须在访问任务用到的资源的时候,对线程进行同步!,可以指定某个线程去执行任务。System.Timers.Timer类:定义一个System.Timers.Timer对象,然后绑定Elapsed事件,通过Start()方法来启动计时,通过Stop()方法或者E...

weixin_42176639的博客 8929

C#定时器实现自动执行的方法

本文实例讲述了C#定时器实现自动执行的方法。分享给大家供大家参考。具体实现方法如下: 代码如下: //下面讲一个打开窗体定时执行按钮的东西 private void Form1_Load(object sender, EventArgs e) { System.Timers.Timer pTimer = new System.Timers.Timer(5000);//每隔5秒执行一次,没用winfrom自带的 pTimer.Elapsed+=pTimer_Elapsed;//委托,要执行的方法 pTimer.AutoReset = true;//获取该定时器自动执行 pTimer.Enabl

TC3xx芯片中断配置避坑指南:从AUTOSAR Davinci配置到SRN地址计算的完整流程

本文详细解析了英飞凌TC3xx芯片的中断配置流程,从AUTOSAR Davinci工具链到硬件调试的全链路指南。重点介绍了中断路由(IR)模块、服务请求节点(SRN)和中断控制单元(ICU)的配置技巧,帮助开发者避开常见陷阱,优化中断性能。

weixin_30628801的博客 419

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

在Web应用程序中执行计划任务(多线程) (转)[@more@]在web应用程序中执行计划任务(多线程) 作者: 孟宪会出自: XML.sz.luohuedu.NET/">【孟宪会之精彩世界】发布日期: 2003-8-...

ciya3282的博客 99

CXL技术入门:从PCIe到高性能计算的桥梁(附最新2.0协议解析)

本文深入解析CXL技术如何作为PCIe的进化版,成为高性能计算的关键桥梁,特别聚焦CXL 2.0协议的关键升级。从技术架构、三大子协议到典型应用场景,全面介绍CXL在缓存一致性、内存共享等方面的优势,帮助开发者快速掌握这一前沿技术。

wdx012345的博客 730
上一篇: 为你的CheckBox和RadioButton控件添色加彩
下一篇: 在.NET应用程序中添加拼写和语法检查功能
java2000_test
博客等级 码龄19年 10粉丝 320原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值