public class Global : System.Web.HttpApplication { private static Timer timer; private static readonly object _syncLock = new object(); public static event SessionRefreshHandler refresh; /// <summary> /// Session定时刷新 /// </summary> /// <param name="state"></param> /// <remarks>监控点数据和告警数据未取得时延时使用</remarks> static void SessionRefresh(object state) { if (refresh!= null) { refresh(); } } void Application_Start(object sender, EventArgs e) { // 在应用程序启动时运行的代码 if (timer == null) { lock (_syncLock) { if (timer == null) { timer = new Timer( new TimerCallback(SessionRefresh), null, 0, 1000 * 120); //2分钟 } } } |
public class SessionHelper : IHttpHandler,IRequiresSessionState { private HttpSessionState curSession; private List<SessionModel> list = new List<SessionModel>(); private int Review = int.Parse(System.Configuration.ConfigurationManager.AppSettings["Review"]); public SessionHelper(HttpSessionState session) { curSession = session; if (curSession["List"]!=null) { list = (List<SessionModel>)curSession["List"]; } //初始化的时候,绑定Golbal刷新事件 Global.refresh += Oper; } |
其实是最基础的事件的应用。 就是要搞明白,
谁是订阅者:订阅者 就是 是要做某事的类。 global需要做刷新,于是是订阅者。
谁被订阅。 给订阅者干活的,书写方法的类。 需要有订阅者的对象来得到订阅者的事件。
给事件绑一个自己的书写的方法。
同时要注意, 被订阅类中的书写的方法, 此方法调用一些 函数传递的参数。 针对参数进行创建对象或者操作。
而且还可以在方法中 调用 一些 本类中的成员。
关于使用本类成员,应该是一种拷贝的概念。 我会做个例子测试的。
经测试,确实会保持原来类的状态和属性。
应该说: 是一种共享。 在其他地方对本类的属性修改后。 不影响事件, 事件在执行时 得到的本类的属性都是实时的。
测试代码:
1.被订阅类, 自主决定什么时候执行事件的类
public class Global : System.Web.HttpApplication { private static Timer timer; private static readonly object _syncLock = new object(); public static event SessionRefreshHandler refresh; /// <summary> /// Session定时刷新 /// </summary> /// <param name="state"></param> /// <remarks>监控点数据和告警数据未取得时延时使用</remarks> static void SessionRefresh(object state) { try { if (refresh!= null) { refresh(); } } catch (Exception ex){ } } void Application_Start(object sender, EventArgs e) { // 在应用程序启动时运行的代码 if (timer == null) { lock (_syncLock) { if (timer == null) { //timer = new Timer( new TimerCallback(SessionRefresh), null, 0, 1000 * 120); //2分钟 timer = new Timer(new TimerCallback(SessionRefresh), null, 0, 100); } } } |
2.订阅类, 指定某个事 让 被订阅类做。 写方法(事)、告诉被订阅类(绑定)
public void Oper() { list = (List<SessionModel>)curSession["List"]; //操作Session 时间。 供Global中定时刷新Global使用。 修改Session等级,负责启动推理流程。 for (int index = 0; index < list.Count; index++) { if (list[index].Currentlevel == 1)// { if ((DateTime.Now - list[index].SessionInTime).Minutes.CompareTo(Review) >= 0)//大于重复时间 { if (list[index].Sourcelevel == 0) { list[index].Sourcelevel = 1; list[index].SessionInTime = DateTime.Now; curSession["List"] = list; //重复计算一遍。 } } } } Add("2");//做测试使用 } |
工具类:Session操作:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.SessionState; using System.Configuration; namespace RuleEngine.Tool { /// <summary> /// Sessionmodel实体类 /// </summary> /// <remarks>如果出现数据未读到的情况,则设置标识本次运行完成后5分钟后再次允许一遍。</remarks> public class SessionModel { private string _sessionNo; private DateTime _sessionInTime= DateTime.Now; private int _currentlevel=0; private int _sourcelevel = 0; #region 定位信息 private int _scCode = 0; public int ScCode { get { return _scCode; } set { _scCode = value; } } private int _ssCode = 0; public int SsCode { get { return _ssCode; } set { _ssCode = value; } } private int _suCode = 0; public int SuCode { get { return _suCode; } set { _suCode = value; } } private int _soCode = 0; public int SoCode { get { return _soCode; } set { _soCode = value; } } #endregion /// <summary> /// session标志--一个推理的标志 /// </summary> public string SessionNo { get { return _sessionNo; } set { _sessionNo = value; } } /// <summary> /// 推理进入时间 /// </summary> public DateTime SessionInTime { get { return _sessionInTime; } set { _sessionInTime = value; } } /// <summary> /// 当前推理级别 /// </summary> /// <remarks> 数据延迟---每次重新执行推理时设置为0,不为0是代表重复计算</remarks> public int Currentlevel { get { return _currentlevel; } set { _currentlevel = value; } } /// <summary> /// 记录上一次的推理级别 /// </summary> public int Sourcelevel { get { return _sourcelevel; } set { _sourcelevel = value; } } public SessionModel() { } public SessionModel(int scCode, int ssCode, int SuCode, int soCode) { this._scCode=scCode; this._ssCode=ssCode; this._suCode=SuCode; this._soCode = soCode; } } /// <summary> /// Session管理类 /// </summary> public class SessionHelper : IHttpHandler,IRequiresSessionState { private HttpSessionState curSession; private List<SessionModel> list = new List<SessionModel>(); private int Review = int.Parse(System.Configuration.ConfigurationManager.AppSettings["Review"]); public SessionHelper(HttpSessionState session) { curSession = session; if (curSession["List"]!=null) { list = (List<SessionModel>)curSession["List"]; } //初始化的时候,绑定Golbal刷新事件 Global.refresh += Oper; } public void ProcessRequest(HttpContext context) { } public bool IsReusable { get { return true; } } //3.操作Session 时间。 供Global中定时刷新Global使用。 修改Session等级,负责启动推理流程。 //4.删除Session 把具体中间结果移到备份数据表中。 //5.停止Session //6.设置30分钟过期的Session,如果规则存在则,对应中间结果设置为停止,并移除中间结果,存入备份库中。Session中也移除,不再进入计算。推送中间结果。 /// <summary> /// 加入Session List中 /// </summary> /// <param name="model"></param> public void Add(string SessionNo) { SessionModel model = new SessionModel(); model.SessionNo = SessionNo; list.Add(model); curSession["List"] = list; } /// <summary> /// 加入Session List中 /// </summary> /// <param name="model"></param> public void Add(SessionModel model) { list.Add(model); curSession["List"] = list; } /// <summary> /// 读取Session List /// </summary> /// <param name="SessionNo"></param> /// <returns></returns> public SessionModel Query(string SessionNo) { list = (List<SessionModel>)curSession["List"]; return list.Find( delegate(SessionModel m) { return m.SessionNo == SessionNo; }); } /// <summary> /// 读取Session索引 /// </summary> /// <param name="SessionNo"></param> /// <returns></returns> public int QueryListIndex(string SessionNo) { list = (List<SessionModel>)curSession["List"]; return list.FindIndex ( delegate(SessionModel m) { return m.SessionNo == SessionNo; }); } public void Oper() { list = (List<SessionModel>)curSession["List"]; //操作Session 时间。 供Global中定时刷新Global使用。 修改Session等级,负责启动推理流程。 for (int index = 0; index < list.Count; index++) { if (list[index].Currentlevel == 1)// { if ((DateTime.Now - list[index].SessionInTime).Minutes.CompareTo(Review) >= 0)//大于重复时间 { if (list[index].Sourcelevel == 0) { list[index].Sourcelevel = 1; list[index].SessionInTime = DateTime.Now; curSession["List"] = list; //重复计算一遍。 } } } } Add("2"); } /// <summary> /// 对外,设置接口 /// </summary> /// <param name="SessionNo"></param> /// <remarks>设置等级, 与Oper配合使用。 等级设置后,Oper自动判断到</remarks> public void Set(string SessionNo) { list = (List<SessionModel>)curSession["List"]; int index = QueryListIndex(SessionNo); if (index != -1 && list[index].Sourcelevel ==0) { list[index].Currentlevel = 1; curSession["List"] = list; } } /// <summary> /// 操作完成后,删除Session,计算完成停止 /// </summary> /// <param name="SessionNo"></param> public void delete(string SessionNo) { list = (List<SessionModel>)curSession["List"]; int index = QueryListIndex(SessionNo); if (index != -1) { //最初不需要重复计算和重复计算过之后可删除 if ((list[index].Currentlevel == 1 && list[index].Sourcelevel == 1) || (list[index].Currentlevel ==0 && list[index].Sourcelevel == 0)) { list.RemoveAt(index); curSession["List"] = list; } } //停止当前的推理。 处理中间结果 } } } |
本人声明:沐海(http://my.oschina.net/mahaisong) 以上文章是经过本人设计实践和阅读其他文档得出。如果需要探讨或指教可以留言!欢迎交流!