Quartz实例及IIS闲置超时解决方案

来源:互联网 发布:一代宗师 知乎 编辑:程序博客网 时间:2024/06/05 20:51
要点:Quartz功能,Quartz实例,Iis闲置超时解决方案
在Web应用中常要实现的一个功能就是:
1)某一个功能模块的代码需要定期执行一次;
2)或者像邮件的定时发送功能一样,一到某个时间点就执行一段代码;
3)每个月最后一周的星期五的18点00分执行一段代码。
那么这个时间就需要一个计时器来执行。但是传统的System.Threading;System.Windows.Forms.Timer;System.Timers;System.Web.UI.Timer;均不能很好的解决上面所说的第三个功能甚至第二个功能,此时,就可以使用Quartz。
和众多的插件一样,Quartz也从Java插件而来,不过在.net中的Quartz使用C#语言编写。

Quartz能做什么?

1) 每天9点00分执行一段代码;
2) 2050年每天09点00分执行一段代码;
3) 每天上午9点到下午18点59分这段时间里每隔10分钟执行一段代码;
4) 每个月最后一周的星期五的18点00分执行一段代码。
… …
以上这些情况都能用Quartz来实现,比起Timer来说,它的时间管理规则强大得多。

Iis闲置超时

一种节省系统资源的方法就是为应用程序池中的工作进程配置闲置超时设置。 配置这些设置后,工作进程会在不活动状态持续指定的一段时间后关闭。 默认的闲置超时值为 20 分钟。
对于它的产生可以简单的理解为:在Web应用程序中,在规定的时间内客户端和服务器没有进行任何一次数据交互,那就会造成 iis闲置超时。
解决方案
1)Application_End中重定向到任何一个可以和服务器进行数据交互的网页,如:Response.Redirect("Index.aspx");
2)另写一个网页,这个网页在iis服务器规定的时间内,定时向服务器取一次数据。
3)猜想:既然是因为超时造成客户端和服务器断开链接,那么是不是可以利用长连接这种技术来解决呢?(只有一个页面,且不为外界访问,避免过多网页长连接超成服务器资源浪费)
在方案一中,最大的问题是会造成断开到重连过程中的一个空隙,如果网站越大,30秒到1分钟以上的时间空隙是存在的,时间一长就要手动的断开(关闭iis)再重启(iis);
在方案二中,不会存在方案一的问题,只是在服务器端,要打开一个网页,然后这个页面在iis闲置超时的时间以内向服务器请求一次数据(注意不是简单的刷新当前页面)。当iis闲置超时为1440,那么这个网站一天有一个访问量就可以保证不会触发到iis闲置超时而执行的资源清理。
在方案三中,这只是一个猜想,但从长连接来说,最终效果不如方案二。

在写具体代码之前,先来看看文件列表:


图一

具体实施

新建IndexJob.cs输入以下代码(定时要执行的代码):
using Quartz;using System.IO;    public class IndexJob:IJob    {        public void Execute(JobExecutionContext context)        {            //取当前应用程序路径            string fileLogPath = AppDomain.CurrentDomain.BaseDirectory;            string fileNmae = fileLogPath + "QuartzTest.txt";            if (!File.Exists(fileNmae))            {                FileStream fs = File.Create(fileNmae);                fs.Dispose();            }            StreamWriter sw = new StreamWriter(fileNmae, true, Encoding.Default);            sw.Write(DateTime.Now.ToString() + "\r\n");            sw.Write("--------------------\r\n");            sw.Flush();//清空缓冲并写入数据            sw.Close();            sw.Dispose();        }    }
新建QuartzAPI.cs输入以下代码:
private static readonly QuartzAPI Quartz = new QuartzAPI();        private QuartzAPI()        {                    }        public static QuartzAPI CreateInstance()        {            return Quartz;        }        public void Start()        {            //IScheduler sched;//调度器            ISchedulerFactory schedulerFactory = new StdSchedulerFactory();//调度工厂            IScheduler sched = schedulerFactory.GetScheduler();//从工厂中调取一个“调度器”            JobDetail job = new JobDetail("job1", "group1", typeof(IndexJob));//作业名称,作业组名,作业要执行的类(这个类要继承IJob)            #region SimpleTrigger            //DateTime ts = TriggerUtils.GetNextGivenSecondDate(null, 5);            //TimeSpan interval = TimeSpan.FromSeconds(5);            //Trigger trigger = new SimpleTrigger("trigger1", "group1", "job1", "group1", ts, null,            //SimpleTrigger.RepeatIndefinitely, interval);            #endregion            Trigger trigger = new CronTrigger("aa", "groupaa", "job1", "group1", "0 0-59 15 * * ?"); //触发器名,触发器组名,任务名,任务组名,时间规则。0 0-59 15 * * ? 后面说明            sched.AddJob(job,true);//为调度器添加任务            sched.ScheduleJob(trigger);//为调度器添加时间计划            sched.Start();//启动调度            //调度器:IScheduler、任务(作业):JobDetail、触发器:Trigger        }    }
把握了调度器:IScheduler、任务(作业):JobDetail、触发器:Trigger,那么使用起来就不难了
在Global中输入以下代码:
        protected void Application_Start(object sender, EventArgs e)        {            QuartzAPI.CreateInstance().Start();//在网站应用程序启动,同时也将定时任务启动起来。        }
以上就是Quartz的使用方法,现在要将先前说过的两种iis闲置超时解决方案应用到Quartz中,不然Quartz是没法在项目中实际使用的。

方案一:

        protected void Application_End(object sender, EventArgs e)        {            //方法一:重新建立客户端和服务器之间的连接            Response.Redirect("WebForm1.aspx");            #region 记录日志,可用log4net或省略本行及以下代码            //取当前应用程序路径            string fileLogPath = AppDomain.CurrentDomain.BaseDirectory;            string fileNmae = fileLogPath + "QuartzTest.txt";            if (!File.Exists(fileNmae))            {                FileStream fs = File.Create(fileNmae);                fs.Dispose();            }            StreamWriter sw = new StreamWriter(fileNmae, true, Encoding.Default);            sw.Write(DateTime.Now.ToString() + "运行到此时结束\r\n");            sw.Write("--------------------\r\n");            sw.Flush();//清空缓冲并写入数据            sw.Close();            sw.Dispose();            Application_Start(sender, e);            #endregion        }
推荐方案二

方案二

新建WebForm1.aspx页面。
在WebForm1.aspx.cs中输入
    public partial class WebForm1 : System.Web.UI.Page    {        //方法一:在iis过期时间内由客户端向服务器请求一次数据,完成客户端和服务器的一次数据交互        protected string timerStr = string.Empty;        protected void Page_Load(object sender, EventArgs e)        {            timerStr = DateTime.Now.ToString();        }    }
在WebForm1.aspx中输入以下代码
<head runat="server">    <title></title>    <script src="Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>    <script type="text/javascript">        //方法二:在iis过期时间内由客户端向服务器请求一次数据,完成客户端和服务器的一次数据交互        $(window).load(function () {            setInterval("sTimeout()", 1000);            setInterval("mySelfqq()", 3000); //这里设置的时间要比IIS中的要短(当前 iis设置为1分钟过期,即50秒也行)        });        function mySelfqq() {            window.location.href("WebForm1.aspx");//重加载        }        function sTimeout() {            var a = Date().toString();            $("#lb").html(a);        }    </script></head><body>    <form id="form1" runat="server">    <div>        llll<div id = "lb"></div>lllll<br/>        <%=timerStr %>//从服务器中最数据    </div>    </form></body>

实例下载地址:

http://download.csdn.net/detail/z1119815468/6571371

关于CronTrigger中时间规则的设置可参考:http://hi.baidu.com/yanlong662/item/503e5014dd598c443a176ea0
原创粉丝点击