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 ...
随机推荐
- linux环境安装nagiosgraph将nagios的性能数据绘制成动态图表?
需求描述: 在安装完成nagios之后,比如有监控磁盘负载信息的,连接数的,进程数的,可以通过安装nagiosgraph软件, 将nagios的性能数据绘制成图表,可以看到一段时间内数据的变化 环境说 ...
- WIN7隐藏GUEST登录账户
在Windows7中,我们有时候需要开启Guest用户,以方便给别的同事共享打印机和部分文件,但同时又不希望别人用Guest账号从本地登陆界面进入本机.这个时候就需要将本地登陆界面的Guest用户进行 ...
- Eclipse------导入项目后出现javax.servlet.jsp cannot be resolved to a type
报错信息:javax.servlet.jsp cannot be resolved to a type 原因1: 这个错误可能是服务器自带的servlet库未导入的原因. 解决方法: 右键项目&quo ...
- 统计js数组中奇数元素的个数
如何统计一个JS数组中奇数元素的个数呢? 这是群友提出的一个问题,大部分群友给出的是遍历 然后对2取模,得到最终结果. 这样的写法是最容易想得到的,那么有没有其他思路呢? 这里我提供另外一种思路,我们 ...
- GC--垃圾收集器
把周末的文章放在现在才来写,是自己太忙了?还是堕落了? 好吧直接进入主题吧,简单干脆的理解会让自己记忆深刻: 首先说明:GC垃圾收集器关注两件事情: 第一件:查找所有存活对象. 第二件:抛弃死对象(不 ...
- 重命名和重定向RF执行生成的output文件
命令: pybot -d output文件保存路径 -o output文件重命名 -d --outputdir dir Where to create output files. The defaul ...
- [Maven]Maven中的一些基本概念
Pom文件中的groupId.artifactId.version和name,这三个元素定义了一个项目的基本的坐标,在Maven世界中,任何的jar.pom或者war都是基于这些基本的坐标惊醒区分. ...
- Linux下用C获取当前时间
Linux下用C获取当前时间,具体如下: 代码(可以把clock_gettime换成time(NULL)) ? 1 2 3 4 5 6 7 8 9 10 void getNowTime() { ti ...
- #pragma init_seg
先进后出原则,最先初始化的最后析构! 1.C++中全局对象.变量的构造函数调用顺序是跟声明有一定关系的,即在同一个文件中先声明的先调用.对于不同文件中的全局对象.变量,它们的构造函数调用顺序是未定义的 ...
- .net页面生命周期【转】
.Net 页面生命周期IIS 所收到的对某 Microsoft ASP.NET 页面的每个请求都被移交给 ASP.NET HTTP 管线.HTTP 管线由一系列托管对象组成,这些对象按顺序处理该请求, ...