Timer应用之Interval优化
开发中, 有时有这种场景,使用 Timer 的 Timer_Elapsed 间隔 执行(如:从数据库)获取数据 与 现有 应用服务器中的 静态变量数据(起到缓存的目的)做 对比 ,若有改变,则 更新当前 静态变量的数据,从而使 数据不再是过期数据,可以继续被使用的目的。
一般来说,直接使用 Timer 的 Timer_Elapsed 也可以,就是 为了 数据比对,达到效果和目的就行。
不过在使用过程中,发现自己定义 的静态变量数据,一般很少情况下,才发生变化, 而 Timer_Elapsed 又总是 固定的时间 Interval 去执行,这样多少有些浪费资源。
为了减少 Timer_Elapsed 的执行,就需要 控制 间隔Interval,就此我写了一个类控制 Interval 的类。
原理: 将 Timer_Elapsed 中的 “是否变化” 记录下来,然后 积累多次(集合存储)的变化后,对其 取 LastCount 个 “是否变化”, 如果 取出来的 都是 没有变化,则 Interval 累加 1秒,然后 再提升 LastCount 的个数,以便下次 取更多 “是否变化”,
来确定 是否可以 再次 Interval 累加 1秒。一直持续,当然得控制 Interval 的最大值 ,防止过大失去 更新到最新数据 的作用。还要提供一个 特殊情况,需要 重置 ,重新开始 收集 “是否变化”进行计算 的功能。
效果:
类代码如下:
/// <summary>
/// 管理 Timer 的 Interval
///
/// 在 Timer 的 Timer_Elapsed 事件中 InsertChangePoint(通过逻辑 得出 这一点的数据是否有变化),将 这一点变化记录下来,
///
/// 积累多次 数据变化点,来进行判断 该变 Timer 的 Interval,从而达到 减少 Timer_Elapsed 执行次数的目的,优化Timer 的作用。
///
/// </summary>
public class IntervalMgr
{
public Timer ExecTimer { get;private set; } /// <summary>
/// Timer默认间隔 单位(毫秒)
/// </summary>
public double DefInterval { get; private set; } /// <summary>
/// 记录变化点的容器
/// </summary>
public List<bool> LstChangePoint
{
get; private set;
} /// <summary>
/// 每次递增的断定个数
/// </summary>
public int IncLastCount { get; private set; } /// <summary>
/// 初始断定个数
/// </summary>
private int LastCount = ; /// <summary>
/// 最大执行间隔 单位(毫秒)
/// </summary>
public double MaxInterval { get; private set; } /// <param name="execTimer">间隔执行的Timer</param>
/// <param name="defInterval">execTimer的默认间隔事件 单位(毫秒)</param>
/// <param name="incLastCount">递增数</param>
/// <param name="maxInterval">最大执行间隔 单位(毫秒)</param>
public IntervalMgr(Timer execTimer, double defInterval,int incLastCount,double maxInterval = ( * * ))
{
this.ExecTimer = execTimer;
this.DefInterval = defInterval;
this.LastCount = incLastCount;
this.IncLastCount = incLastCount;
this.MaxInterval = maxInterval;
this.LstChangePoint = new List<bool>();
} /// <summary>
/// 在 Timer_Elapsed 事件 调用 InsertChangePoint
/// </summary>
/// <param name="isChange">(检测数据)是否发生变化</param>
public void InsertChangePoint(bool isChange)
{
LstChangePoint.Add(isChange);
Console.WriteLine("LastCount:"+ LastCount + "\r\nLstChangePoint.Count:" + LstChangePoint.Count + "\r\nLstChangePoint:" + string.Join(",", LstChangePoint)); if (CanJudg(LastCount))
{
if (JudgIsNotChange(LastCount))
{
if ((ExecTimer.Interval + ) < MaxInterval)// 小于 最大间隔,则 继续累加 1 秒 。
{
ExecTimer.Interval = (ExecTimer.Interval + );
LastCount = LastCount + IncLastCount; //下次 要累加 1秒 所需的 检测变化的个数
}
else
{
ExecTimer.Interval = MaxInterval; //大于 最大间隔,则以 最大间隔 进行执行
LstChangePoint.RemoveRange(, );
}
}
else
{
//一旦有变化则重置。
ReStart();
}
}
} /// <summary>
/// 特殊情况下,需要执行重置方法
/// </summary>
public void ReStart()
{
LstChangePoint.Clear();
ExecTimer.Interval = DefInterval;
LastCount = IncLastCount;
} /// <summary>
/// 是否可以断定最后 lastCout 个变化点
/// </summary>
/// <param name="lastCout"></param>
/// <returns></returns>
private bool CanJudg(int lastCout)
{
if (lastCout <= )
{
return false;
}
return LstChangePoint.Count >= lastCout;
} /// <summary>
/// 最后 lastCout 个都没变化?
/// </summary>
/// <param name="lastCout"></param>
/// <returns></returns>
private bool JudgIsNotChange(int lastCout)
{
if (LstChangePoint.Count >= lastCout)
{
var lstTake = LstChangePoint.Skip(LstChangePoint.Count - lastCout).Take(lastCout).ToList();
return lstTake.TrueForAll(t => !t);//全部都为false,则就是全部都没有进行过变化
}
else
{
throw new Exception("积累的变化点还不足以判断出最后" + lastCout + "个变化点是否都发生变化!");
}
}
}
测试Demo: https://files.cnblogs.com/files/lztkdr/IntervalMgrDemo.zip
Timer应用之Interval优化的更多相关文章
- 利用libevent的timer实现定时器interval
在不怎么了解libevent的情况下,看到timer这个关键字想到可以用来做定时任务,官方资料也不齐全,就从代码里看到了TIMEOUT字样,这么说来应该是支持timeout了,那interval呢,貌 ...
- angular性能优化心得
原文出处 脏数据检查 != 轮询检查更新 谈起angular的脏检查机制(dirty-checking), 常见的误解就是认为: ng是定时轮询去检查model是否变更.其实,ng只有在指定事件触发后 ...
- AngularJS性能优化心得,自己踩过的抗,及一些别人的经验(转哦)
脏数据检查 != 轮询检查更新 谈起angular的脏检查机制(dirty-checking), 常见的误解就是认为: ng是定时轮询去检查model是否变更.其实,ng只有在指定事件触发后,才进入$ ...
- Kanzi编程基础1 - 定时器Timer
Kanzi虽然发生了比较多的版本更迭,api也发生了很多变化,但定时器的头文件一直都在一个地方:#include "user/include/user/ui/message/kzu_mess ...
- System.Windows.Forms.Timer反编译学习
using System; using System.ComponentModel; using System.Globalization; using System.Runtime; using S ...
- System.Windows.Forms.Timer
一.主要属性.方法和事件 Windows 窗体 Timer 是定期引发事件的组件.该组件是为 Windows 窗体环境设计的. 时间间隔的长度由 Interval 属性定义,其值以毫秒为单位.若启用了 ...
- [置顶] STM32移植contiki进阶之三(中):timer 中文版
鉴于自己英语水平不高,在这里,将上一篇关于contiki 的timer的文章翻译为中文,让自己在学习的时候,更方便点.文中有许多不是很通顺的地方,将就吧. Timers Contiki系统提供了一套时 ...
- setTimeout模拟interval
/** * @param fn: {Function} // function which to execute * @param timer: {number} // gap time betwee ...
- Linux时间子系统之二:Alarm Timer
一.前言 严格来讲Alarm Timer也算POSIX Timer一部分,包含两种类型CLOCK_REALTIME_ALARM和CLOCK_BOOTTIME_ALARM.分别是在CLOCK_REALT ...
随机推荐
- Python 面向对象详解
Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. 如果你以前没有接触过面向对象的编程语言,那你 ...
- 内省Introspector(反射操作javaBean)
一:内省是一种特殊的反射,来更方便的操作javaBean对象,通过内省可以获取到类字节码的描述器, 然后解剖每一个字段,获取每个字段的读写方法,即get/set方法的反射,然后获取或者是封装bean的 ...
- mysql中json_replace函数的使用?通过json_replace对json对象的值进行替换
需求描述: 在看mysql中关于json的内容,通过json_replace函数可以实现对json值的替换, 在此记录下. 操作过程: 1.查看带有json数据类型的表 mysql> selec ...
- mysql数据库中查看当前使用的数据库是哪个数据库?
环境描述: mysql版本:5.5.57-log 操作系统版本:Red Hat Enterprise Linux Server release 6.6 (Santiago) 需求说明: 查看当前使用的 ...
- [SLAM] Little about SLAM
Books from Zhihu: 幽默一把 看完Gonzalez:嗯,好像很好玩的样子,我也来搞一搞.看完Price:什么鬼,怎么这么多公式,公式看不懂肿么破.看完Szeliski:原来用一千页的书 ...
- task.factory.startnew()
1.委托: public delegate int Math(int param1,int param2);定义委托类型 Public int Add(int param1,int param2)// ...
- SpringBoot------集成MyBatis
1.pom.xml文件添加MyBatis和MySQL等依赖 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns: ...
- 7 -- Spring的基本用法 -- 9...容器中Bean的生命周期
7.9 容器中Bean的生命周期 Spring可以管理singleton作用域的Bean的生命周期,Spring可以精确地知道该Bean何时被创建,何时被初始化完成.容器何时准备销毁该Bean实例. ...
- 【Android】ProgressBar
http://www.cnblogs.com/wangying222/p/5304990.html http://www.cnblogs.com/plokmju/p/android_ProgressB ...
- ArcGIS应用
1.ArcGIS Server发布资源报错:网络资源问题 有可能是跟网络相关的服务没有开启,开启相关服务器后有可能可以解决此问题. 还有可能通过此法解决:开始--控制面板--网络和共享中心--高级共享 ...