C#实现Web应用程序定时启动任务

简介:

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

由于ASP.NET站点是作为Web应用程序运行的,它并不受线程的限制,因此我们可以非常方便地在Application_Start和Application_End事件中建立和销毁一个计划任务。

ASP.NET 框架应用程序在第一次向服务器发出请求时创建,在此之前,不执行 ASP.NET 代码。当第一个请求发出后,将创建一个 HttpApplication 实例池并引发 Application_Start 事件。
HttpApplication 实例处理该请求以及后面的请求,直到最后一个实例退出并引发 Application_End 事件。

IIS应用池回收造成Application_Start中定时执行程序停止的问题的解决方法

原理就是在应用程序结束时发出一个Web请求访问网站,启动Application_Start。

 

 
  1. void Application_End(object sender, EventArgs e)   
  2. {   
  3. // 在应用程序关闭时运行的代码   
  4. //解决应用池回收问题   
  5. System.Threading.Thread.Sleep(5000);   
  6. string strUrl = "网站地址";   
  7. System.Net.HttpWebRequest _HttpWebRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strUrl);   
  8. System.Net.HttpWebResponse _HttpWebResponse = (System.Net.HttpWebResponse)_HttpWebRequest.GetResponse();   
  9. System.IO.Stream _Stream = _HttpWebResponse.GetResponseStream();//得到回写的字节流   

下面就简单介绍一下在Web站点实现计划任务的方法。我们的例子是定时往文件里添加信息,作为例子,这里把当前的时间定时地写入文件中。

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

public interface ISchedulerJob
{
void Execute();
}

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

 

 
  1. public 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. }  

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

 

 
  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. }  

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

 

 
  1. public class Scheduler  
  2. {  
  3. private SchedulerConfiguration configuration = null;  
  4.  
  5. public Scheduler(SchedulerConfiguration config)  
  6. {  
  7. configconfiguration = 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. }  


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

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

 
  1. protected void Application_End(Object sender, EventArgs e)  
  2. {  
  3. if (null != schedulerThread)  
  4. {  
  5. schedulerThread.Abort();  
  6. }  

 

好了,在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">
<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>

本文转自linzheng 51CTO博客,原文链接:http://blog.51cto.com/linzheng/1078714


相关文章
|
22天前
|
开发框架 前端开发 .NET
C#编程与Web开发
【4月更文挑战第21天】本文探讨了C#在Web开发中的应用,包括使用ASP.NET框架、MVC模式、Web API和Entity Framework。C#作为.NET框架的主要语言,结合这些工具,能创建动态、高效的Web应用。实际案例涉及企业级应用、电子商务和社交媒体平台。尽管面临竞争和挑战,但C#在Web开发领域的前景将持续拓展。
|
1天前
|
存储 安全 数据安全/隐私保护
Web应用程序的会话管理是一种跟踪和识别特定用户与Web服务器之间交互的技术
Python Web开发中,会话管理用于跟踪用户与服务器交互,如Flask框架提供的内置功能。以下是一个简单示例:安装Flask后,设置应用密钥,通过session读写用户状态。例如,创建一个显示和设置用户名称的Web应用,用户提交的名字将保存在会话中。在生产环境中,应安全存储密钥,如使用环境变量。扩展会话管理可借助第三方库实现更多功能,但可能需更多配置。
6 2
|
4天前
|
XML 开发框架 .NET
C#/ASP.NET应用程序配置文件app.config/web.config的增、删、改操作
C#/ASP.NET应用程序配置文件app.config/web.config的增、删、改操作
|
7天前
|
SQL 存储 C#
C# Web控件与数据感应之 TreeView 类
C# Web控件与数据感应之 TreeView 类
|
7天前
|
SQL 存储 Oracle
C# Web控件与数据感应之 CheckBoxList 类
C# Web控件与数据感应之 CheckBoxList 类
|
7天前
|
SQL 存储 Oracle
C# Web控件与数据感应之 Control 类
C# Web控件与数据感应之 Control 类
|
7天前
|
SQL 存储 Oracle
C# Web控件与数据感应之 ListControl 类
C# Web控件与数据感应之 ListControl 类
|
7天前
|
SQL 存储 Oracle
C#利用IDbCommand实现通用数据库脚本执行程序
C#利用IDbCommand实现通用数据库脚本执行程序
|
14天前
|
缓存 前端开发 JavaScript