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


相关文章
|
2天前
|
SQL 安全 测试技术
漏洞扫描技术:对Web应用程序进行漏洞扫描
漏洞扫描技术:对Web应用程序进行漏洞扫描
11 1
|
3天前
|
Rust 网络协议 应用服务中间件
granian:让你的 Web 应用程序快如闪电
granian:让你的 Web 应用程序快如闪电
18 2
|
1天前
|
云安全 SQL 安全
数字时代下的Web应用程序安全:漏洞扫描服务的功能与优势
在当今这个数字化时代,Web应用程序不仅是企业与用户之间互动的桥梁,更是企业展示服务、传递价值的核心平台。然而,随着技术的不断进步,Web应用程序的复杂性也在不断增加,这为恶意攻击者提供了可乘之机。安全漏洞的频发,如SQL注入、跨站脚本攻击(XSS)、跨站请求伪造(CSRF)等,严重威胁着企业的数据安全、服务稳定性乃至经济利益。在这样的背景下,漏洞扫描服务作为一道重要的安全防线,显得尤为重要。本文将深入探讨漏洞扫描服务在面对Web应用程序安全问题时,所具备的功能优势。
|
1天前
|
安全 API C#
C# 如何让程序后台进程不被Windows任务管理器强制结束
C# 如何让程序后台进程不被Windows任务管理器强制结束
6 0
|
2天前
|
安全 Java Linux
Kali渗透测试:通过Web应用程序实现远程控制
Kali渗透测试:通过Web应用程序实现远程控制
25 0
|
2天前
|
存储 缓存 安全
如何使用 PHP 将天气跟踪集成到 Web 应用程序中
如何使用 PHP 将天气跟踪集成到 Web 应用程序中
11 0
|
2天前
|
API C#
C#实现Winform程序右下角弹窗消息提示
C#实现Winform程序右下角弹窗消息提示
12 0
|
2天前
|
API C#
异步轮询 Web API 的实现与 C# 示例
异步轮询 Web API 的实现与 C# 示例
8 0
|
28天前
|
C# 容器
C#中的命名空间与程序集管理
在C#编程中,`命名空间`和`程序集`是组织代码的关键概念,有助于提高代码的可维护性和复用性。本文从基础入手,详细解释了命名空间的逻辑组织方式及其基本语法,展示了如何使用`using`指令访问其他命名空间中的类型,并提供了常见问题的解决方案。接着介绍了程序集这一.NET框架的基本单位,包括其创建、引用及高级特性如强名称和延迟加载等。通过具体示例,展示了如何创建和使用自定义程序集,并提出了针对版本不匹配和性能问题的有效策略。理解并善用这些概念,能显著提升开发效率和代码质量。
40 4
|
1月前
|
Linux C# 开发者
Uno Platform 驱动的跨平台应用开发:从零开始的全方位资源指南与定制化学习路径规划,助您轻松上手并精通 C# 与 XAML 编程技巧,打造高效多端一致用户体验的移动与桌面应用程序
【9月更文挑战第8天】Uno Platform 的社区资源与学习路径推荐旨在为初学者和开发者提供全面指南,涵盖官方文档、GitHub 仓库及社区支持,助您掌握使用 C# 和 XAML 创建跨平台原生 UI 的技能。从官网入门教程到进阶技巧,再到活跃社区如 Discord,本指南带领您逐步深入了解 Uno Platform,并提供实用示例代码,帮助您在 Windows、iOS、Android、macOS、Linux 和 WebAssembly 等平台上高效开发。建议先熟悉 C# 和 XAML 基础,然后实践官方教程,研究 GitHub 示例项目,并积极参与社区讨论,不断提升技能。
39 2