在项目中我们或多或少的遇到一些需要定时触发或者计算的东西,这个时候我们就需要定时器来作为解决方案。非常好思路清晰,业务逻辑完好,定时器也开好了,
当我们信心满满的挂到IIS服务器的时候,发现写的定时器在运行了一段时间之后就不在运行了。
问题分析:
难道是我们的代码写错了吗?不是的,如果写错了怎么又会正常运行几次哪。那问题出在哪里拉,没有错问题在于IIS的程序池。
定时器与闲时超时的冲突:
首先我们分析原因一:没有错你没有看错,IIS还有一个显示超时设置,他会被回收程序池进程。系统一般默认的时间为20分钟,所有也就是说我们的程序如果
5分钟一次也就运行4次就停止掉了。用过Quartz定时任务的小伙伴们都知道吧(深受其苦)。知道是这个东西捣的鬼那就修改他,
方法一:修改他的值,但是很不幸,它最大值也就1740分钟。也就是下面说的第二个问题了,耐心等待。
方法二:不让他闲时超时,所谓的闲时超时就是此网站多少时间没有人访问工作,那你就可以一直访问他,长时间开启一个机器,写一个对此网站的时间小于
闲时超时时间的轮询吧。
程序池的限制:
程序池存在时间限制,我们通过IIS---->引用程序池---->高级设置---->找到回收会发现固定时间间隔为1740.这里就是上面说的显示超时最大时长了。
这是IIS自己的功能,那么又有人说那我把他设置为0(嘿嘿),我个人理解就是你设置为0也不是不回收而是不为固定时间间隔回收。下面附上代码解决方案。
解决程序池回收:
找到原因那就可以对症下药了,既然是自动回收了,那我们只要阻止程序池的自动回收就好了吗?
1 protected void Application_End(object sender, EventArgs e) 2 { 3 //下面的代码是关键,可解决IIS应用程序池自动回收的问题 4 Thread.Sleep(1000); 5 //这里设置你的web地址,可以随便指向你的任意一个aspx页面甚至不存在的页面,目的是要激发Application_Start <br> 6 //我这里是一个验证token的地址。 7 string url = System.Configuration.ConfigurationManager.AppSettings["tokenurl"]; 8 HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url); 9 HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse(); 10 Stream receiveStream = myHttpWebResponse.GetResponseStream();//得到回写的字节流 11 }
原理:程序池回收中会触发Application_End事件,在此事件中重新请求网站任意地址,相当于重新激活该网站防止回收。