C#自己编写定时器
来源:互联网 发布:linux中的解压缩命令 编辑:程序博客网 时间:2024/06/07 02:56
我们在写winfrom时经常会用到定时器,比如客户端通过socket定时向服务器发送检测包等。.netframework提供了一个定时器控件System.Windows.Forms.Timer,使用很方便。
其实通过C#多线程也可以实现定时器功能。我的做法大致为:新开一个线程用于计时,当时间间隔过后用事件timerover实现主窗体中的定时函数,再通过调用contro.invoke方法返回主窗体线程执行定时后的操作。
先定义两个类,timer类用于管理和配置定时器,interval_date用于计算两个时刻的间隔(例如2010年1月1日和2012年12月26日之间的毫秒),单位是毫秒,因此定时器的设置范围理论上可以无限大。原理不多说,下面放代码:
timer类代码:
public class timer { int count = 0; public delegate void Deletimerover(int count); public event Deletimerover timerover; private int time; public int Time { set { time = value; } get { return time; } } private bool enable; public bool Enable { set { enable = value; } } public timer() { } public timer(int t) { time = t; } public void start_time() { Thread rd = new Thread(new ThreadStart(start)); rd.IsBackground = true; count = 0; rd.Start(); } private void start() { DateTime dt_tem = DateTime.Now; interval_date interval = new interval_date(); while (interval.interval_millisec(dt_tem,DateTime.Now) < time) ; if (!enable) { return; } else { timerover(++count); start(); } } }
interval_date类代码:
public class interval_date { public long interval_millisec(DateTime dt1,DateTime dt2) { long interval = 0; interval += com_year(dt1,dt2); interval += com_month(dt1,dt2); interval += com_day(dt1,dt2); interval += com_hour(dt1, dt2); interval += com_minute(dt1, dt2); interval += com_second(dt1, dt2); interval += com_millisecond(dt1, dt2); return interval; } private long com_year(DateTime dt1, DateTime dt2) { int year1 = dt1.Year; int year2 = dt2.Year; long interval = 0; if (year1 != year2) { for (int i = year1 + 1; i < year2; i++) { for(int j = 1; j <= 12; j++) { interval += DateTime.DaysInMonth(i, j); } } } interval = interval * 24 * 3600 * 1000; return interval; } private long com_month(DateTime dt1, DateTime dt2) { int year1 = dt1.Year; int year2 = dt2.Year; int month1 = dt1.Month; int month2 = dt2.Month; long interval = 0; if (year1 != year2) { for (int i = month1 + 1; i <= 12; i++) { interval += DateTime.DaysInMonth(year1, i); } for (int i = 1; i < month2; i++) { interval += DateTime.DaysInMonth(year2, i); } } else { for (int i = month1+1; i < month2; i++) { interval += DateTime.DaysInMonth(year1, i); } } interval = interval * 24 * 3600 * 1000; return interval; } private long com_day(DateTime dt1,DateTime dt2) { int year1 = dt1.Year; int year2 = dt2.Year; int month1 = dt1.Month; int month2 = dt2.Month; int day1 = dt1.Day; int day2 = dt2.Day; long interval = 0; if (year1 == year2 && month1 == month2) { if(day2 == day1) { return 0; } interval = day2-day1-1; } else { interval += DateTime.DaysInMonth(year1, month1) - day1; interval += day2-1; } interval = interval * 24 * 3600 * 1000; return interval; } private long com_hour(DateTime dt1, DateTime dt2) { long interval = 0; if (dt1.Year == dt2.Year && dt1.Month == dt2.Month && dt1.Day == dt2.Day) { if (dt1.Hour == dt2.Hour) { return 0; } interval += dt2.Hour - dt1.Hour - 1; } else { interval += 24 - dt1.Hour - 1; interval += dt2.Hour; } interval = interval * 3600 * 1000; return interval; } private long com_minute(DateTime dt1, DateTime dt2) { long interval = 0; if (dt1.Year == dt2.Year && dt1.Month == dt2.Month && dt1.Day == dt2.Day && dt1.Hour == dt2.Hour) { if (dt1.Minute == dt2.Minute) { return 0; } interval += dt2.Minute - dt1.Minute - 1; } else { interval += 60 - dt1.Minute - 1; interval += dt2.Minute; } return interval * 60 * 1000; } private long com_second(DateTime dt1, DateTime dt2) { long interval = 0; if (dt1.Year == dt2.Year && dt1.Month == dt2.Month && dt1.Day == dt2.Day && dt1.Hour == dt2.Hour && dt1.Minute == dt2.Minute) { if (dt1.Second == dt2.Second) { return 0; } interval += dt2.Second - dt1.Second - 1; } else { interval += 60 - dt1.Second - 1; interval += dt2.Second; } return interval * 1000; } private long com_millisecond(DateTime dt1, DateTime dt2) { long interval = 0; if (dt1.Year == dt2.Year && dt1.Month == dt2.Month && dt1.Day == dt2.Day && dt1.Hour == dt2.Hour && dt1.Minute == dt2.Minute && dt1.Second == dt2.Second) { interval += dt2.Millisecond - dt1.Millisecond; } else { interval += 1000 - dt1.Millisecond; interval += dt2.Millisecond; } return interval; } }
最后就是使用方式了
public partial class Form1 : Form { public timer newtimer = new timer(); delegate void Time(int count); public void TimeOver(int count) { labelX1.Text = count.ToString(); } public Form1() { InitializeComponent(); newtimer.Time = 1000; newtimer.timerover +=new timer.Deletimerover(newtimer_timerover); } void newtimer_timerover(int count) { Time dd = new Time(TimeOver); this.Invoke(dd, new object[] { count}); } private void buttonX1_Click(object sender, EventArgs e) { buttonX1.Enabled = false; newtimer.Enable = true; newtimer.Time = int.Parse(textBoxX1.Text); newtimer.start_time(); } private void buttonX2_Click(object sender, EventArgs e) { newtimer.Enable = false; buttonX1.Enabled = true; labelX1.Text = "0"; textBoxX1.Text = "1000"; } }
一个文本框两个按钮,按钮一用来开启定时器,按钮二用来复位。
通过简单的验证,这种方法和.netframework提供的timer控件实现的定时误差在个位数(毫秒),也可以尝试用更精确的方法来测试一下。
0 0
- C#自己编写定时器
- C#自己编写软键盘
- C#定时器
- C#定时器
- c# 定时器
- C#定时器
- C#定时器
- C# 定时器
- C#定时器
- C#定时器
- C#定时器
- C#定时器
- C#定时器
- c#定时器
- c#定时器
- C# 定时器
- C#定时器
- c#定时器
- 发现apache的mod_python存在一个BUG
- Hadoop生态上几个技术的关系与区别:hive、pig、hbase 关系与区别
- HDU 4268 Alice and Bob(lower_bound)
- 【hdoj1005】Number Sequence
- Java图形化组件
- C#自己编写定时器
- test2
- js 闭包
- CornerStone commit不成功解决方案
- Linux Shell下的后台运行及其前台的转换 http://mobile.51cto.com/others-446925.htm
- MYSQL 创建用户
- 沈阳微信二维码营销技巧(不得不看)
- 关于定义布局OnMeasure 的总结
- 拆字