ASP.NET如何定时执行任务

33 篇文章 0 订阅
asp.net如何定时执行任务

根据不同需求,在web开发中,有时候我们可能要定时的执行一下任务,比如定时发布网站中的文章,这时我们就需要做一个定时执行更新的操作,但由于web的http是无状态的连接,如何才能时时进行任务的更新呢?方法还是有的,看看下面两种方法吧!

方法一:

?
using System; 
    
     using System.Data; 
    
     using System.Configuration; 
    
     using System.Collections; 
    
     using System.Web; 
    
     using System.Web.Security; 
    
     using System.Web.SessionState; 
    
     using System.Timers; 
    
     using System.Net; 
    
     using System.IO; 
    
     using System.Text; 
    
     using System.Threading; 
    
     namespace qumiao.com 
    
    { 
    
     public class Global : System.Web.HttpApplication 
    
    { 
    
     protected void Application_Start( object sender, EventArgs e) 
    
    { 
    
     //定义定时器 
    
    System.Timers.Timer myTimer = new System.Timers.Timer(5000); 
    
    myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed); 
    
    myTimer.Enabled = true
    
    myTimer.AutoReset = true
    
    } 
    
     void myTimer_Elapsed( object source, ElapsedEventArgs e) 
    
    { 
    
     try
    
    { 
    
    Log.SaveNote(DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss" ) + ":AutoTask is Working!" ); 
    
    YourTask(); 
    
    } 
    
     catch (Exception ee) 
    
    { 
    
    Log.SaveException(ee); 
    
    } 
    
    } 
    
     void YourTask() 
    
    { 
    
     //在这里写你需要执行的任务 
    
    } 
    
     protected void Application_End( object sender, EventArgs e) 
    
    { 
    
    Log.SaveNote(DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss" ) + ":Application End!" ); 
    
     //下面的代码是关键,可解决IIS应用程序池自动回收的问题 
    
    Thread.Sleep(1000); 
    
     //这里设置你的web地址,可以随便指向你的任意一个aspx页面甚至不存在的页面,目的是要激发Application_Start 
    
     string url = http: //www.shaoqun.com 
    
    HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url); 
    
    HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse(); 
    
    Stream receiveStream = myHttpWebResponse.GetResponseStream(); //得到回写的字节流 
    
    } 
    
    } 
    
    } 

  原理:Global.asax 可以是asp.net中应用程序或会话事件处理程序,我们用到了Application_Start(应用程序开始事件)和Application_End(应用程序结束事件)。当应用程序开始时,启动一个定时器,用来定时执行任务YourTask()方法,这个方法里面可以写上需要调用的逻辑代码,可以是单线程和多线程。当应用程序结束时,如IIS的应用程序池回收,让asp.net去访问当前的这个web地址。这里需要访问一个aspx页面,这样就可以重新激活应用程序。Log类是一个记录日志的一个类,下面是测试时生成的日志信息: 
     
     ================================================================ 
     
     2008-10-30 17:46:10:AutoTask is Working! 
     
     2008-10-30 17:46:15:AutoTask is Working! 
     
     2008-10-30 17:46:20:AutoTask is Working! 
     
     2008-10-30 17:46:23:Application End! 
     
     2008-10-30 17:46:29:AutoTask is Working! 
     
     2008-10-30 17:46:34:AutoTask is Working! 
     
     从日志中发现,当手动回收IIS的应用程序池之后,计划任务还在执行,说明我们的目的达到了。 
     
     如果将Application_End中的代码注释掉,会发现Application End之后,计划任务停止工作了,如下: 
     
     ================================================================ 
     
     2008-10-30 18:01:34:AutoTask is Working! 
     
     2008-10-30 18:01:39:AutoTask is Working! 
     
     2008-10-30 18:01:44:AutoTask is Working! 
     
     2008-10-30 18:01:46:Application End! 
     
     局限性:可以解决应用程序池自动或者手动回收,但是无法解决IIS重启或者web服务器重启的问题,当然这种情况出现的时候不多,而且如果有人访问你的网站的时候,又会自动激活计划任务了。 

方法二:

?
<%@ Application Language= "C#" %> 
     
     <%@ import Namespace= "System.IO" %> 
     
     <script runat= "server"
     
      void Application_Start( object sender, EventArgs e) 
     
     { 
     
      // 在应用程序启动时运行的代码 
     
     System.Timers.Timer myTimer = new System.Timers.Timer(10000); 
     
     myTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent); 
     
     myTimer.Interval = 10000; 
     
     myTimer.Enabled = true
     
     } 
     
      void Application_End( object sender, EventArgs e) 
     
     { 
     
      //  在应用程序关闭时运行的代码 
     
     } 
     
      void Application_Error( object sender, EventArgs e) 
     
     { 
     
      // 在出现未处理的错误时运行的代码 
     
     } 
     
      void Session_Start( object sender, EventArgs e) 
     
     { 
     
      // 在新会话启动时运行的代码 
     
     } 
     
      void Session_End( object sender, EventArgs e) 
     
     { 
     
      // 在会话结束时运行的代码。 
     
      // 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为 
     
      // InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer 
     
      // 或 SQLServer,则不会引发该事件。 
     
     } 
     
      private static void OnTimedEvent( object source, System.Timers.ElapsedEventArgs e) 
     
     { 
     
      //间隔时间执行某动作 
     
      //指定日志文件的目录 
     
      string fileLogPath = AppDomain.CurrentDomain.BaseDirectory + "SystemLog"
     
      string fileLogName = "SoftPrj_CN_" + DateTime.Now.ToLongDateString() + "_log.txt"
     
      //定义文件信息对象 
     
     FileInfo finfo = new FileInfo(fileLogPath + fileLogName); 
     
      //创建只写文件流 
     
      using (FileStream fs = finfo.OpenWrite()) 
     
     { 
     
      //根据上面创建的文件流创建写数据流 
     
     StreamWriter strwriter = new StreamWriter(fs); 
     
      //设置写数据流的起始位置为文件流的末尾 
     
     strwriter.BaseStream.Seek(0, SeekOrigin.End); 
     
      //写入错误发生时间 
     
     strwriter.WriteLine( "发生时间: " + DateTime.Now.ToString()); 
     
      //写入日志内容并换行 
     
      //strwriter.WriteLine("错误内容: " + message); 
     
     strwriter.WriteLine( "错误内容: " ); 
     
      //写入间隔符 
     
     strwriter.WriteLine( "---------------------------------------------" ); 
     
     strwriter.WriteLine(); 
     
      //清空缓冲区内容,并把缓冲区内容写入基础流 
     
     strwriter.Flush(); 
     
      //关闭写数据流 
     
     strwriter.Close(); 
     
     fs.Close(); 
     
     } 
     
     } 
     
     </script> 
    

  方法三:

?
<%@ Application Language= "C#" %> 
<%@ Import Namespace= "System.IO" %> 
<%@ Import Namespace= "System.Threading" %> 
<script RunAt= "server"
string LogPath; 
Thread thread; 
void WriteLog() 
while ( true
StreamWriter sw = new StreamWriter(LogPath, true , Encoding.UTF8); 
sw.WriteLine(thread.Name + ":" + DateTime.Now.ToString()); 
sw.Close(); 
Thread.CurrentThread.Join(1000 * 10); //阻止10秒 
void Application_Start( object sender, EventArgs e) 
LogPath = HttpContext.Current.Server.MapPath( "log.txt" );        //在应用程序启动时运行的代码 
thread = new Thread( new ThreadStart(WriteLog)); 
thread.Name = "写登录日志线程"
thread.Start(); 
void Application_End( object sender, EventArgs e) 
//  在应用程序关闭时运行的代码 
void Application_Error( object sender, EventArgs e) 
// 在出现未处理的错误时运行的代码 
void Session_Start( object sender, EventArgs e) 
// 在新会话启动时运行的代码 
void Session_End( object sender, EventArgs e) 
// 在会话结束时运行的代码。 
// 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为 
// InProc 时,才会引发 Session_End 事件。如果会话模式设置为 StateServer 
// 或 SQLServer,则不会引发该事件。 
</script>
 
 
 
ASP.NET后台定时执行任务
 

现在有很多网站或系统需要在服务端定时做某件事情,如每天早上8点半清理数据库中的无效数据

首先在asp.net中的项目中新建一个全局文件Global.asax

然后在Application_Start 事件中 启动定时器,如需要每隔多少秒来做一件事情,在这里我以每隔1秒来执行对Application["timer"] 的累加,即在后台执行,与客服端无关,即使客户端全部都关闭,那么后台仍然执行。

如下代码写在Application_start事件中

            System.Timers.Timer timer = new System.Timers.Timer(1000);
            timer.Elapsed += new System.Timers.ElapsedEventHandler(AddCount);

            //AddCount是一个方法,此方法就是每个1秒而做的事情
            timer.AutoReset = true;
            //给Application["timer"]一个初始值
            Application.Lock();
            Application["timer"] = 1;
             Application.UnLock();
            timer.Enabled = true;

然后自定义AddCount方法 格式如下:

      private void AddCount(object sender, ElapsedEventArgs e)
        {    

             Application.Lock();
             Application["timer"] = Convert.ToInt32(Application["timer"])+1;

           //这里可以写你需要执行的任务,比如说,清理数据库的无效数据或增加每个用户的积分等等
            Application.UnLock();

    

}

然后在客户端获取Application["timer"]的值,当第一个用户打开网页时 显示1,然后关闭网站,等个10秒,再打开网站 ,那么显示的就是10,本人经过测试,可以实现每天8点钟准时刷新数据库

  

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值