C# winform中自定义精确定时器(经测试稳定可靠)
原C#的定时器时间越长,误差越大。
在主动请求设备数据的使用,使用C#的几种自带定时器导致每天都会丢失几条数据。
经测试使用自定义的定时器可完全解决此问题。
使用方法:
MillisecondTimer _sysTimer;
_sysTimer = new MillisecondTimer();
_sysTimer.Tick += sysTimer_Tick; ;
_sysTimer.Interval = 1000; //每秒执行
_sysTimer.Start();
private void sysTimer_Tick(object sender, EventArgs e)
{
//需要定时执行的内容
}
自定义类(MillisecondTimer.cs)如下:
using System;
using System.Runtime.InteropServices;
using System.ComponentModel; namespace TEST
{
public sealed class MillisecondTimer : IComponent, IDisposable
{ private static TimerCaps caps;
private int interval;
private bool isRunning;
private int resolution;
private TimerCallback timerCallback;
private int timerID; public int Interval
{
get
{
return this.interval;
}
set
{
if ((value < caps.periodMin) || (value > caps.periodMax))
{
throw new Exception("超出计时范围!");
}
this.interval = value;
}
} /// <summary>
///
/// </summary>
public bool IsRunning
{
get
{
return this.isRunning;
}
} /// <summary>
///
/// </summary>
public ISite Site
{
set;
get;
} public event EventHandler Disposed; // 这个事件实现了IComponet接口
public event EventHandler Tick; static MillisecondTimer()
{
timeGetDevCaps(ref caps, Marshal.SizeOf(caps));
} public MillisecondTimer()
{
this.interval = caps.periodMin; //
this.resolution = caps.periodMin; // this.isRunning = false;
this.timerCallback = new TimerCallback(this.TimerEventCallback); } public MillisecondTimer(IContainer container)
: this()
{
container.Add(this);
} ~MillisecondTimer()
{
timeKillEvent(this.timerID);
} public void Start()
{
if (!this.isRunning)
{
this.timerID = timeSetEvent(this.interval, this.resolution, this.timerCallback, , ); // 间隔性地运行 if (this.timerID == )
{
throw new Exception("无法启动计时器");
}
this.isRunning = true;
}
} public void Stop()
{
if (this.isRunning)
{
timeKillEvent(this.timerID);
this.isRunning = false;
}
} /// <summary>
/// 实现IDisposable接口
/// </summary>
public void Dispose()
{
timeKillEvent(this.timerID);
GC.SuppressFinalize(this);
EventHandler disposed = this.Disposed;
if (disposed != null)
{
disposed(this, EventArgs.Empty);
}
} //*************************************************** 内部函数 ******************************************************************
[DllImport("winmm.dll")]
private static extern int timeSetEvent(int delay, int resolution, TimerCallback callback, int user, int mode); [DllImport("winmm.dll")]
private static extern int timeKillEvent(int id); [DllImport("winmm.dll")]
private static extern int timeGetDevCaps(ref TimerCaps caps, int sizeOfTimerCaps);
// The timeGetDevCaps function queries the timer device to determine its resolution. private void TimerEventCallback(int id, int msg, int user, int param1, int param2)
{
if (this.Tick != null)
{
this.Tick(this, null); // 引发事件
}
} //*************************************************** 内部类型 ****************************************************************** private delegate void TimerCallback(int id, int msg, int user, int param1, int param2); // timeSetEvent所对应的回调函数的签名 /// <summary>
/// 定时器的分辨率(resolution)。单位是ms,毫秒
/// </summary>
[StructLayout(LayoutKind.Sequential)]
private struct TimerCaps
{
public int periodMin;
public int periodMax;
} }
}
C# winform中自定义精确定时器(经测试稳定可靠)的更多相关文章
- Winform中自定义xml配置文件后对节点进行读取与写入
场景 Winform中自定义xml配置文件,并配置获取文件路径: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100522648 ...
- Winform中自定义添加ZedGraph右键实现设置所有Y轴刻度的上下限
场景 Winforn中实现ZedGraph自定义添加右键菜单项(附源码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...
- Winform中自定义ZedGraph右键复制成功后的提示
场景 Winform中实现ZedGraph中曲线右键显示为中文: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100115292 ...
- Winform中自定义xml配置文件,并配置获取文件路径
场景 在Winform程序中,需要将一些配置项存到配置文件中,这时就需要自定义xml的配置文件格式.并在一些工具类中去获取配置文件的路径并加载其内容. 关注公众号霸道的程序猿获取编程相关电子书.教程推 ...
- C# winform中自定义用户控件 然后在页面中调用用户控件的事件
下面是用户控件的代码: using System; using System.Collections.Generic; using System.ComponentModel; using Syste ...
- c#(winform)中自定义ListItem类方便ComboBox添加Item项
1.定义ListItem类 public class ListItem { private string _key = string.Empty; private string _value = st ...
- WinForm中自定义搜索框(水印、清空按钮、加载中图标)
public partial class CustomSearchBar : TextBox { private readonly Label lblwaterText = new Label(); ...
- C# Winform中自定义筛选及自带统计行的Datagridview控件
网上分享有很多种自制DGV控件,都有不小的缺陷. 没办法,按需求自己定制了一个. 一.过滤方面类似于Excel的筛选功能.支持右键菜单筛选,同时也支持在文本框输入文字按焦点列进行筛选: 二.统计行我采 ...
- Winform中对自定义xml配置文件进行Xml节点的添加与删除
场景 Winform中自定义xml配置文件后对节点进行读取与写入: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10053213 ...
随机推荐
- linux下安装配置jdk(解压版)
在linux下登录oracle官网,下载解压版jdk 传送门 系统默认下载到"下载"目录中 创建要将该文件解压的文件夹: 其中 -p 参数代表递归创建文件夹(可以创建多级目录 ...
- thinkphp后台向前台传值没有传过去的小问题
if($listyyarr){ $this->assign('listyyarr',$listyyarr); //$this->assign('nowDated',$endDated); ...
- C#-获取字符的GBK编码值
public static int GetGBKValue(string key) { byte[] gbk = Encoding.GetEncoding("GBK").GetBy ...
- Python内置函数(35)——next
英文文档: next(iterator[, default]) Retrieve the next item from the iterator by calling its __next__() m ...
- 你考虑清楚了吗就决定用 Bootstrap ?
近年来,在前端项目中, Bootstrap 已经成为了一个非常受欢迎的工具. Bootstrap 的确有很多优点,然而,如果你的团队中恰好有一个专职的前端工程师.那我推荐你们不要使用 Bootstra ...
- emqtt 试用(七)追踪
追踪 EMQ 消息服务器支持追踪来自某个客户端(Client)的全部报文,或者发布到某个主题(Topic)的全部消息. 追踪客户端(Client): ./bin/emqttd_ctl trace cl ...
- 敏捷项目需求拆解&发现用户故事
需求文档和敏捷中的Epic,User Story, Task之间是什么关系以及如何将需求文档转换成敏捷方式的描述,指导开发人员. 一直是很多公司团队比较困扰的问题,那么最近笔者为了解决这些问题,上了一 ...
- 表单中各种input汇总
html表单 表单用于搜集不同类型的用户输入,表单由不同类型的标签组成,相关标签及属性用法如下: 1.<form>标签 定义整体的表单区域 action属性 定义表单数据提交地址 meth ...
- 【已解决】React中配置Sass引入.scss文件无效
React中配置Sass引入.scss文件无效 在react中使用sass时,引入.scss文件失效 尝试很多方法没法解决,最终找到解决方法,希望能帮助正在坑里挣扎的筒子~ 在node_modules ...
- SublimeText用FileHeader给代码文件生成头部注释
https://github.com/shiyanhui/FileHeader 修改的模板在这个路径下:C:\Users\[USERNAME]\AppData\Roaming\Sublime Text ...