Environment.TickCount,

官网介绍:一个 32 位带符号整数,它包含自上次启动计算机以来所经过的时间(以毫秒为单位)。

*由于 TickCount 属性值的值是32位有符号整数,因此,如果系统连续运行,TickCount 将从零递增到 Int32.MaxValue 大约24.9 天,然后跳转到 Int32.MinValue,这是一个负数,然后在下一个24.9 天内递增为零。

我们可以通过实时获取系统启动后的毫秒数来实现定时器的定时功能;

首先建立一个Timer类,声明变量如下:

        enum_State State;//定时器State
int startTime; //开始时间
int endTime; //结束时间
int interval; //定时间隔
int stopTime; //停止时间
int pauseTime; //暂停时间
bool outMax; //是否超出Int32.MaxValue

定时器状态如下,初始状态为Idle:

        enum enum_State
{
_Idle,
_Busy,
_TimeOut,
_Stopped,
_Pause
}

定时器开始启动函数,定时参数为整数,单位ms:

        public void Start(int time)
{
if (time <= )
time = ;
interval = time;
startTime = Environment.TickCount;
endTime = startTime + interval;
State = enum_State._Busy;
stopTime = ;
pauseTime = ;
outMax = endTime < startTime;
}

定时器停止函数:

        public void Stop()
{
if (IsBusy() || IsPause())
stopTime = Environment.TickCount;
State = enum_State._Stopped;
endTime = ;
pauseTime = ;
}

暂停定时器:

        public void Pause()
{
if (pauseTime == )
pauseTime = Environment.TickCount;
State = enum_State._Pause;
}

继续定时器:

        public void Resume()
{
if (!IsPause())
return;
int val = pauseTime;
startTime = Environment.TickCount - val;
endTime = startTime + interval;
State = enum_State._Busy;
pauseTime = ;
stopTime = ;
outMax = endTime < startTime;
}

重置定时器:

        public void Reset()
{
interval = ;
startTime = ;
endTime = ;
pauseTime = ;
stopTime = ;
State = enum_State._Idle;
}

判断是否超时:

        public bool IsTimeOut()
{
int ticks = Environment.TickCount;
if (outMax)
{
if (ticks < startTime)
outMax = false;
}
if (!outMax && !IsPause())
{
if (IsBusy() && (ticks > endTime || ticks <= && endTime > && startTime > ))
{
stopTime = endTime;
State = enum_State._TimeOut;
}
}
return State == enum_State._TimeOut;
}

下面在程序中实例化一个Timer类timer1,并实现定时2s发送消息:

        public void Monitor()
{
timer1.Start(*);
while (true)
{
Thread.Sleep();
//int i = Thread.CurrentThread.ManagedThreadId;
if (timer1.IsTimeOut())
{
comUp.comPort_SendData(textBox_ComSend.Text);
timer1.Start(*);
}
}
}

看一下定时效果:

因为调用Winform窗台显示,线程执行,逻辑判断等需要一些时间,所以显示有一些偏差;

如官网介绍,使用Environment.TickCount时,注意24.9天左右会达到Int32.MaxValue,然后跳转到Int32.MinValue,再经过24.9天达到0,要注意对负数的处理;

C#使用Environment.TickCount 自定义的定时器类的更多相关文章

  1. C# winform中自定义精确定时器(经测试稳定可靠)

    原C#的定时器时间越长,误差越大. 在主动请求设备数据的使用,使用C#的几种自带定时器导致每天都会丢失几条数据. 经测试使用自定义的定时器可完全解决此问题. 使用方法: MillisecondTime ...

  2. Android 自定义Activity基类与TitleBar

    我们在开发App的时候有时候碰到多个界面有一个共同点的时候,比如,都有相同的TitleBar,并且TitleBar可以设置显示的文字.TitleBar上的点击事件,如果给每一个Activity都写一遍 ...

  3. hadoop编程小技巧(5)---自定义输入文件格式类InputFormat

    Hadoop代码测试环境:Hadoop2.4 应用:在对数据需要进行一定条件的过滤和简单处理的时候可以使用自定义输入文件格式类. Hadoop内置的输入文件格式类有: 1)FileInputForma ...

  4. WPF自定义窗口基类

    WPF自定义窗口基类时,窗口基类只定义.cs文件,xaml文件不定义.继承自定义窗口的类xaml文件的根节点就不再是<Window>,而是自定义窗口类名(若自定义窗口与继承者不在同一个命名 ...

  5. Silverlight实例教程 - 自定义扩展Validation类,验证框架的总结和建议(转载)

    Silverlight 4 Validation验证实例系列 Silverlight实例教程 - Validation数据验证开篇 Silverlight实例教程 - Validation数据验证基础 ...

  6. 利用NSUserdefaults来存储自定义的NSObject类及自定义类数组

    利用NSUserdefaults来存储自定义的NSObject类及自定义类数组 1.利用NSUserdefaults来存储自定义的NSObject类 利用NSUserdefaults也可以来存储及获取 ...

  7. NSTimer定时器类

    NSTimer是Cocoa中比较常用的定时器类,基本操作如下: handleTimer方法可以自行定义.在需要的地方创建timer即可,handleTimer就可以每0.5秒执行一次.   - (vo ...

  8. 安卓开发37:自定义的HorizontalScrollView类,使其pageScroll的时候焦点不选中

    自定义一个HorizontalScrollView类,主要为了让这个HorizontalScrollView不能鼠标点击,不能左右按键,并且没有焦点. public class ImageMoveHo ...

  9. WPF自学入门(九)WPF自定义窗口基类

    今天简单记录一个知识点:WPF自定义窗口基类,常用winform的人知道,winform的窗体继承是很好用的,写一个基础窗体,直接在后台代码改写继承窗体名.但如果是WPF要继承窗体,我个人感觉没有理解 ...

随机推荐

  1. Elasticsearch系列---结构化搜索

    概要 结构化搜索针对日期.时间.数字等结构化数据的搜索,它们有自己的格式,我们可以对它们进行范围,比较大小等逻辑操作,这些逻辑操作得到的结果非黑即白,要么符合条件在结果集里,要么不符合条件在结果集之外 ...

  2. 小白学Java:RandomAccessFile

    目录 小白学Java:RandomAccessFile 概述 继承与实现 构造器 模式设置 文件指针 操作数据 读取数据 read(byte b[])与read() 追加数据 插入数据 小白学Java ...

  3. Linux防火墙之iptables常用扩展匹配条件(二)

    上一篇博文我们讲到了iptables的一些常用的扩展匹配模块以及扩展模块的一些选项的说明,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12273755.htm ...

  4. DOCKER 学习笔记7 Docker Machine 在阿里云实例化ECS 以及本地Windows 实例化虚拟机实战

    前言 通过以上6小节的学习,已经可以使用DOCKER 熟练的部署应用程序了.大家都可以发现使用 DOCKER 带来的方便之处,因为现在的话,只是在一台服务器上部署,这样部署,我们只需要一条命令,需要的 ...

  5. 9. Palindrome Number QuestionEditorial Solution

    Determine whether an integer is a palindrome. Do this without extra space. click to show spoilers. S ...

  6. 使用Java迭代器实现Python中的range

    如果要想迭代一个类的对象,那么该类必须实现 Iterable 接口,然后通过 iterator 方法返回一个 Iterator 实例. Range 类实现了Python中的range的所有用法,如:r ...

  7. 机器学习(ML)七之模型选择、欠拟合和过拟合

    训练误差和泛化误差 需要区分训练误差(training error)和泛化误差(generalization error).前者指模型在训练数据集上表现出的误差,后者指模型在任意一个测试数据样本上表现 ...

  8. GAN tensorflow 实作

    从2014年Ian Goodfellow提出GANs(Generative adversarial networks)以来,GANs可以说是目前深度学习领域最为热门的研究内容之一,这种可以人工生成数据 ...

  9. HDU3836 Equivalent Sets (Tarjan缩点+贪心)

    题意: 给你一张有向图,问你最少加多少条边这张图强连通 思路: 缩点之后,如果不为1个点,答案为出度为0与入度为0的点的数量的最大值 代码: #include<iostream> #inc ...

  10. Go语言实现:【剑指offer】二进制中1的个数

    该题目来源于牛客网<剑指offer>专题. 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 分析: 如果一个整数不为0,那么这个整数至少有一位是1.如果我们把这个整数减1 ...