/// <summary> /// 路由处理 /// </summary> /// <param name="isu">数据接口</param> /// <param name="sug">定时器,用于堵塞</param> public void routeProcess(ISrcUrl isu, SrcUrlGroupTimer sug) { if (isu.USEPARAM) { IMakeParam ip = isu as IMakeParam; List <AqiParam> paramList = ip.enumParams(); while (paramList == null || paramList.Count == 0) { bool bEvent = ThrowWaitEvent(isu.NAME + ":缺少参数,请输入以下参数", isu); if (bEvent) { //若接受事件 //由用户生成参数 //TEST等待用户输入参数 sug.Wait(); } else { //不接受事件则无法输入参数,忽略 ThrowEvent(RunMessage.RunType.TIP, isu.NAME + ":缺少参数,而且无法获取忽略此数据接口"); return; } } foreach (AqiParam ap in paramList) { getProcess(isu, ap); } } else { getProcess(isu, null); } }
/// <summary> /// 添加timer /// </summary> /// <param name="timer"></param> public bool Add(SrcUrlGroupTimer timer) { try { this.thisLock.EnterUpgradeableReadLock(); if (this.dictTimer.ContainsKey(timer.Name)) { //合并 return(this.dictTimer[timer.Name].Union(timer)); } else { this.thisLock.EnterWriteLock(); this.dictTimer.Add(timer.Name, timer); timer.Elapsed += new ElapsedEventHandler(timer_RunEvent); timer.Start(); this.thisLock.ExitWriteLock(); } } finally { this.thisLock.ExitUpgradeableReadLock(); } return(true); }
/// <summary> /// 默认构造 /// 合并运行模式使用 /// </summary> /// <param name="aqiManage"></param> /// <param name="srcUrls"></param> public AqiRunner(AqiManage aqiManage, Dictionary <string, ISrcUrl> srcUrls) { name = "DefaultRunner"; sugtlist = SrcUrlGroupTimer.BuildList(srcUrls); ias = aqiManage.AqiSave; an = aqiManage.AqiNote; ar = aqiManage.AqiRetry; }
/// <summary> /// 一般构造 /// 独立运行模式使用 /// </summary> /// <param name="aqiManage"></param> /// <param name="listSrcUrl"></param> /// <param name="name">名称一般同 数据源tag</param> public AqiRunner(AqiManage aqiManage, List <ISrcUrl> listSrcUrl, string name) { this.name = name; this.dictTimer = SrcUrlGroupTimer.CreateList(listSrcUrl, new Action <object, ElapsedEventArgs>(this.timer_RunEvent)); this.ias = aqiManage.AqiSave; this.an = aqiManage.AqiNote; this.ar = aqiManage.AqiRetry; this.thisLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); }
private ReaderWriterLockSlim thisLock; //读写锁 #endregion #region 构造 /// <summary> /// 默认构造 /// 合并运行模式使用 /// </summary> /// <param name="manage"></param> /// <param name="listSrcUrl"></param> public AqiRunner(AqiManage manage, List <ISrcUrl> listSrcUrl) { this.name = "DefaultRunner"; this.dictTimer = SrcUrlGroupTimer.CreateList(listSrcUrl, new Action <object, System.Timers.ElapsedEventArgs>(this.timer_RunEvent)); this.ias = manage.AqiSave; this.an = manage.AqiNote; this.ar = manage.AqiRetry; this.thisLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); }
/// <summary> /// 添加 数据源接口 /// </summary> /// <param name="srcUrls">接口集合</param> public void AddSrcUrl(Dictionary <string, ISrcUrl> srcUrls) { //转为Timer集合 Dictionary <string, SrcUrlGroupTimer> list = SrcUrlGroupTimer.BuildList(srcUrls); foreach (SrcUrlGroupTimer timer in list.Values) { Add(timer); } }
/// <summary> /// 添加timer /// </summary> /// <param name="timer"></param> public void Add(SrcUrlGroupTimer timer) { if (sugtlist.ContainsKey(timer.Name)) { sugtlist[timer.Name].Union(timer); } else { sugtlist.Add(timer.Name, timer); timer.StartFirst(timerRun); } }
/// <summary> /// 添加 数据源接口 /// </summary> /// <param name="dictSrcUrl">接口集合</param> public bool AddSrcUrl(Dictionary <string, ISrcUrl> dictSrcUrl) { //转为Timer集合 Dictionary <string, SrcUrlGroupTimer> list = SrcUrlGroupTimer.CreateList(dictSrcUrl); foreach (SrcUrlGroupTimer timer in list.Values) { Add(timer); } return(true); }
/// <summary> /// 运行处理 /// </summary> /// <param name="source">定时器</param> /// <param name="e">定时器参数</param> private void timerRun(object source, System.Timers.ElapsedEventArgs e) { SrcUrlGroupTimer sug = source as SrcUrlGroupTimer; ThrowEvent(RunMessage.RunType.TIP, sug.Name + ":定时任务开始执行"); sug.Handle(this); //foreach (ISrcUrl isu in sug.SrcUrl.Values) //{ // routeProcess(isu, sug); //} ThrowEvent(RunMessage.RunType.TIP, sug.Name + ":定时任务开始休眠"); }
/// <summary> /// 获取处理 /// </summary> /// <param name="isu">数据接口</param> /// <param name="sugt">定时器</param> public void GetProcess(ISrcUrl isu, SrcUrlGroupTimer sugt) { byte[] data = null; try { data = isu.GetData(); } catch (Exception exception) { AqiManage.Remind.Log_Error("数据获取失败,进入重试队列", new string[] { this.name, sugt.Name, isu.Name }); this.ar.PutNew(this.name, isu, null, exception); return; } this.SaveProcess(data, isu, null); }
/// <summary> /// 运行处理 /// Elapsed事件放在这里主要是为了能够获取Runner /// </summary> /// <param name="source">定时器</param> /// <param name="e">定时器参数</param> private void timer_RunEvent(object source, System.Timers.ElapsedEventArgs e) { SrcUrlGroupTimer timer = source as SrcUrlGroupTimer; if (e != null) { Thread.CurrentThread.Name = timer.Name + "_Timer(Timer)"; //TODO 设置Runner timer等信息到线程上下文 } AqiManage.Remind.Log_Debug("定时任务开始执行", new string[] { this.name, timer.Name }); if (timer.Handle(this)) { AqiManage.Remind.Log_Debug("定时任务开始休眠", new string[] { this.name, timer.Name }); } else { AqiManage.Remind.Log_Debug("定时器人为取消", new string[] { this.name, timer.Name }); } }
/* * Process处理函数应该保持线程安全 * Runner下的多个Timer会调用此Runner的处理函数 * * */ /// <summary> /// 路由处理 /// 应该由Timer线程调用,可能会嵌套 /// 再此方法中调用的方法应保证线程安全 /// </summary> /// <param name="isu">数据接口</param> /// <param name="sugt">定时器,用于堵塞</param> public void RouteProcess(ISrcUrl isu, SrcUrlGroupTimer sugt) { //加载配置 if (isu.IAW is ICacheConfig) { ICacheConfig icc = isu.IAW as ICacheConfig; if (!icc.IsSrcUrlEnabled(isu.Tag)) { return; } } //双向确认是否使用参数 if (isu.UseParam && isu is ISrcUrlParam) { this.GetProcess(isu as ISrcUrlParam, sugt); } else { this.GetProcess(isu, sugt); } }
//TODO 应该合并GetProcess /// <summary> /// /// 获取处理 /// </summary> /// <param name="isup"></param> /// <param name="sugt"></param> public void GetProcess(ISrcUrlParam isup, SrcUrlGroupTimer sugt) { //获取参数 List <AqiParam> list = null; ISrcUrl isu = isup as ISrcUrl; try { if (isup is ICacheParam) { ICacheParam icp = isup as ICacheParam; if (icp.IsParamsExpired()) { icp.LoadParams(); } list = icp.FilterParams(); } else { list = isup.EnumParams(); } } catch (Exception ex) { AqiManage.Remind.Log_Error("获取参数错误,错误严重无法继续", ex, this.name, sugt.Name, isu.Name); return; } //TODO //应该在检验参数 while ((list == null) || (list.Count == 0)) { if (isup.ParamIgnoreEmpty) { AqiManage.Remind.Log_Error("缺少参数,此数据接口在无参数是将被忽略", new string[] { this.name, sugt.Name, isu.Name }); return; } if (this.ThrowWaitEvent(isu.Name + ":缺少参数,请输入以下参数", isu)) { AqiManage.Remind.Log_Debug("缺少参数,进入等待", new string[] { this.name, sugt.Name, isu.Name }); sugt.Wait(); } else { AqiManage.Remind.Log_Error("缺少参数,而且无法获取忽略此数据接口", new string[] { this.name, sugt.Name, isu.Name }); return; } } foreach (AqiParam ap in list) { if (sugt.IsCancellationRequested) { break; } byte[] data = null; try { data = isup.GetData(ap); } catch (Exception ex) { AqiManage.Remind.Log_Error("数据获取失败,进入重试队列", ex, new string[] { this.name, sugt.Name, isu.Name }); this.ar.PutNew(this.name, isu, ap, ex); } this.SaveProcess(data, isu, ap); } }