定时执行。。。。在webform中实现真的有点别扭,会因各种因素而停止执行,比如
1:web服务停止了一段时间内没人访问;
2:莫名其妙的不执行;
3:……
所以,95%有经验的人会选择使用webservice+客户端的方式来实现。
而我这里介绍的偏偏是使用纯Global.asax实现。
前提,我要实现的是定时处理数据库里的过期信息,比如业务员跟踪的业务到期释放、一个月未登录的用户自动锁定等等。
备注:要是需要实现定时对外发信之类的功能就不合适了,为什么呢?因为所谓定时收信的时间参照是外界的,即便你的站点"死"了,时间依然在走,那么此时一旦到了时间而你的站点处理“死”的状态,必然就收不到信了。而处理系统内的业务数据就不一样了,假设你的站点是“死”的,又何来业务?有业务的前提是:站点是正常的。说到这你明白了一些吗?
扯远了,下面就说说具体步骤吧:
第一步,打开Web.config,在appSettings下新建
第二步,新建Global.asax,打开Global.asax.cs
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.Timers;
namespace CGWCS.WebFile
{
public class Global : System.Web.HttpApplication
{
public static HttpContext myContext = HttpContext.Current;
protected void Application_Start(object sender, EventArgs e)
{
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(TimeEvent);
aTimer.Interval = 1000;// 设置引发时间的时间间隔 此处设置为1秒
aTimer.Enabled = true;
}
private void TimeEvent(object source, ElapsedEventArgs e)
{
// 得到 hour minute second 如果等于某个值就开始执行某个程序。
int intHour = e.SignalTime.Hour;
int intMinute = e.SignalTime.Minute;
int intSecond = e.SignalTime.Second;
// 设置 每天的7:30:00开始执行程序
//假设web服务异常或正常的重启,则强行执行一次任务(目的是为防止遗漏)
if ((intHour == 7 && intMinute == 30 && intSecond == 0) || myContext.Application["AutoTask_1"] == null)
{
string _url = ServerUrl() + "/autotask.aspx?oper=Release1&password=" + System.Configuration.ConfigurationManager.AppSettings["AutoTask:Password"];
System.IO.StreamWriter sw = new System.IO.StreamWriter(myContext.Request.PhysicalApplicationPath + "\\log.txt", true, System.Text.Encoding.UTF8);
sw.WriteLine(e.SignalTime.ToString());
sw.WriteLine(GetHttpPage(_url));
sw.Close();
sw.Dispose();
myContext.Application.Lock();
myContext.Application["AutoTask_1"] = "true";
myContext.Application.UnLock();
}
// 设置 每天的7:45:00开始执行程序
//假设web服务异常或正常的重启,则强行执行一次任务(目的是为防止遗漏)
if ((intHour == 7 && intMinute == 45 && intSecond == 0) || myContext.Application["AutoTask_2"] == null)
{
string _url = ServerUrl() + "/autotask.aspx?oper=Release2&password=" + System.Configuration.ConfigurationManager.AppSettings["AutoTask:Password"];
System.IO.StreamWriter sw = new System.IO.StreamWriter(myContext.Request.PhysicalApplicationPath + "\\log.txt", true, System.Text.Encoding.UTF8);
sw.WriteLine(e.SignalTime.ToString());
sw.WriteLine(GetHttpPage(_url));
sw.Close();
sw.Dispose();
myContext.Application.Lock();
myContext.Application["AutoTask_2"] = "true";
myContext.Application.UnLock();
}
}
private string ServerUrl()
{
if (myContext.Request.Url.Port == 80)
return "http://" + myContext.Request.Url.Host;
else
return "http://" + myContext.Request.Url.Host + ":" + myContext.Request.Url.Port;
}
private string AppPath()
{
string _ApplicationPath = myContext.Request.ApplicationPath;
if (_ApplicationPath != "/")
_ApplicationPath += "/";
return _ApplicationPath;
}
private string GetHttpPage(string url)
{
string strResult = string.Empty;
try
{
System.Net.WebClient MyWebClient = new System.Net.WebClient();
MyWebClient.Credentials = System.Net.CredentialCache.DefaultCredentials;
MyWebClient.Encoding = System.Text.Encoding.UTF8;
strResult = MyWebClient.DownloadString(url);
}
catch (Exception)
{
strResult = "页面获取失败";
}
return strResult;
}
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}
protected void Application_End(object sender, EventArgs e)
{
}
}
}
第三步:新建一个autotask.aspx,打开autotask.aspx.cs
using System;
using System.Data;
using System.Web;
namespace CGWCS.WebFile
{
public partial class _autotask : CGWCS.UI.BasicPage
{
private string _operType = string.Empty;
private string _response = string.Empty;
protected void Page_Load(object sender, EventArgs e)
{
this._operType = q("oper");
switch (this._operType)
{
case "Release1":
Release1();
break;
case "Release2":
Release2();
break;
default:
DefaultResponse();
break;
}
Response.Write(this._response);
}
private void DefaultResponse()
{
this._response = "未知操作";
}
private void Release1()
{
string _password = q("password");
if (_password != System.Configuration.ConfigurationManager.AppSettings["AutoTask:Password"])
{
this._response = "密码错误";
return;
}
....这是释放代码
int _doCount = 释放的个数;
if (_doCount > 0)
{
this._response = "成功释放" + _doCount + "个锁定的企业";
}
else
this._response = "没有可以释放的锁定的企业";
}
private void Release2()
{
string _password = q("password");
if (_password != System.Configuration.ConfigurationManager.AppSettings["AutoTask:Password"])
{
this._response = "密码错误";
return;
}
....这是锁定代码
int _doCount = 锁定的用户数;
if (_doCount > 0)
{
this._response = "成功锁定" + _doCount + "个用户";
}
else
this._response = "没有可以锁定的用户";
}
}
}
最后说明一下,虽然编译通过,但是在Global.asax.cs里有些代码是不生效的,比如:
1、不能直接使用HttpContext.Current,需要先定义一个静态值。
2、Request.ServerVariables["Server_Port"].ToString() 和 Request.Url.Port 同时表示当前web服务端口号,但是只能用后者而不能用前者
[责任编辑:jumbot]