原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中自定义精确定时器(经测试稳定可靠)的更多相关文章

  1. Winform中自定义xml配置文件后对节点进行读取与写入

    场景 Winform中自定义xml配置文件,并配置获取文件路径: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100522648 ...

  2. Winform中自定义添加ZedGraph右键实现设置所有Y轴刻度的上下限

    场景 Winforn中实现ZedGraph自定义添加右键菜单项(附源码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...

  3. Winform中自定义ZedGraph右键复制成功后的提示

    场景 Winform中实现ZedGraph中曲线右键显示为中文: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100115292 ...

  4. Winform中自定义xml配置文件,并配置获取文件路径

    场景 在Winform程序中,需要将一些配置项存到配置文件中,这时就需要自定义xml的配置文件格式.并在一些工具类中去获取配置文件的路径并加载其内容. 关注公众号霸道的程序猿获取编程相关电子书.教程推 ...

  5. C# winform中自定义用户控件 然后在页面中调用用户控件的事件

    下面是用户控件的代码: using System; using System.Collections.Generic; using System.ComponentModel; using Syste ...

  6. c#(winform)中自定义ListItem类方便ComboBox添加Item项

    1.定义ListItem类 public class ListItem { private string _key = string.Empty; private string _value = st ...

  7. WinForm中自定义搜索框(水印、清空按钮、加载中图标)

    public partial class CustomSearchBar : TextBox { private readonly Label lblwaterText = new Label(); ...

  8. C# Winform中自定义筛选及自带统计行的Datagridview控件

    网上分享有很多种自制DGV控件,都有不小的缺陷. 没办法,按需求自己定制了一个. 一.过滤方面类似于Excel的筛选功能.支持右键菜单筛选,同时也支持在文本框输入文字按焦点列进行筛选: 二.统计行我采 ...

  9. Winform中对自定义xml配置文件进行Xml节点的添加与删除

    场景 Winform中自定义xml配置文件后对节点进行读取与写入: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10053213 ...

随机推荐

  1. excel2003和excel2007文件的创建和读取

    excel2003和excel2007文件的创建和读取在项目中用的很多,首先我们要了解excel的常用组件和基本操作步骤. 常用组件如下所示: HSSFWorkbook excel的文档对象 HSSF ...

  2. Nginx在windows环境下的安装与简单配置

    版权声明:本文为博主原创文章,未经博主允许不得转载. 一. 下载并安装Nginx 去Nginx官网下载 我这里选取nginx/Windows-1.10.3版本,下载后解压出来即可,解压出来的路径不能含 ...

  3. 1-51单片机WIFI学习(开发板介绍)

    源码链接都在后面 前面的都是介绍单独的WIFI,没有和单片机结合起来,因为做项目很少会只用WIFI模块.大多数都是WIFI模块作为中转数据的桥梁,单片机负责 数据采集,控制等等,所以自己准备出一套51 ...

  4. Python3 re模块(正则表达式)

    一:什么是正则? 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则. (在Python中)它内嵌在Python中,并通过r ...

  5. python实现:最长子字符串

    给定一个字符串 s 和正整数 n,请使用你熟悉的编程语言输出 s 中包含不超过 n 种字符的最长子串,如 s="uabbcadbaef",n=4 时应该输出 "abbca ...

  6. Python基础数据类型之int、bool、str

    数据类型:int  bool  str  list  元祖  dict  集合 int:整数型,用于各种数学运算. bool:只有两种,True和False,用户判断. str:存储少量数据,进行操作 ...

  7. Django 框架介绍

    Django 框架介绍 MVC框架和MTV框架 简单了解一下什么是MVC框架.MVC(Model View Controller),是模型(model)-视图(view)-控制器(controller ...

  8. python/数据类型和变量

    数据类型和变量 数据类型 计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是, 计算机能处理的远不止数值,还可以处理文本.图形.音频.视频.网页等各种各样的数据, ...

  9. SpringBoot(六):springboot热部署

    在j2ee项目开发中,热部署插件是JRebel.JRebel的使用为开发人员带来了极大的帮助,且挺高了开发便捷.而在SpringBoot开发生态环境中,SpringBoot热部署常用插件是:sprin ...

  10. zookeeper初探

    安装三台linux虚拟机,安装好java环境,并配置好网络以及host文件,分别改好hostname为node0.node1.node2 上传下载好的zookeeper文件到node0的/usr/lo ...