C#自己編寫定時器
我們在寫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控制元件實現的定時誤差在個位數(毫秒),也可以嘗試用更精確的方法來測試一下。
相關推薦
C#自己編寫定時器
我們在寫winfrom時經常會用到定時器,比如客戶端通過socket定時向伺服器傳送檢測包等。.netframework提供了一個定時器控制元件System.Windows.Forms.Timer,使用很方便。 其實通過C#多執行緒也可以實現定時器功能。我的做法大
自己定義定時器(Timer)
mil 動態 初始化 span 標誌位 定時器 ace ram run 近期做項目的時候,用到了java.util.Timer定時器類。也初步使用了,個人感覺不錯。只是,在某些方面Timer類無法滿足項目的需求。比方,在使用Timer時,調用schedule()方
[Visual Studio C++] [MFC] 普通定時器講解
一.前言 定時器是我們在工程中使用較多的一個工具,這裡提供一個入門的普通定時器,一共需要三個函式: SetTimer() KillTimer() OnT
C# 中的定時器2
一、單執行緒定時器 1.System.Windows.Forms.Timer WinForms定時器;單執行緒定時器,執行緒安全;執行在UI執行緒,可直接更新UI畫面;執行效率不高,適用於小任務。 2.System.Windows.Threading.Dispatcher
c# Timer event 定時器事件
1 簡介 實現定時器事件,每隔一個時間後觸發事件。 2.原理 2.1 名稱空間 using System.Timers; 2.2 宣告定時器 private Timer aTimer; 2.3 例項化定時器並設定屬性 // Create a time
java編寫定時器
1.用ajav編寫定時器,首先需要繼承TimerTask類重寫其方法 2.程式碼如下 public class DingShi extends TimerTask { public void
MFC,win32,linux C中SetTimer定時器用法
if(定時條件) { //Timeout to run first time tick.it_value.tv_sec = 10; tick.it_value.tv_usec = 0; //A
VS程式設計,C#後臺建立定時器的一種方法
定時器用於以一定的時間間隔處理一段後臺程式。 1. 新增using 2. 建立定時器 這裡直接定時器的建立與啟動都寫在了建構函式裡,隨著介面開啟 ,定時就啟動。 1)時間間隔這裡用的是以秒為單位,可
C#中的定時器
定時器分兩種,一種是阻塞方式,一種是非阻塞 @1.1:阻塞方式的定時器,呼叫sleep使當前執行緒休眠,終端無法輸入字元 class Program { static void Main(string[] args) {
C#自己編寫的Window服務安裝成功後啟動出現錯誤
自己編寫的Window服務安裝成功後啟動出現錯誤"某些服務在未由其他服務或程式使用時將自動停止",查了變天都不知道啥回事,後面發現原來是自己程式碼有誤,導致服務報錯終止。如果一般看不錯哪裡錯,可以到“
libevent之 C++ RAII封裝 定時器
前言: 這兩天讀Bitcoin程式碼,不禁感慨作者的強大,程式碼的精妙不是我這碼農虔誠膜拜便能讀懂的,更遠遠談不上企及。於是默默埋頭,回想本屌,工作七年還是個默默無聞不及格的碼農,黯然內流~~C/C++那種非人性化的吐槽: 相信很多童鞋跟本農一樣,吃過飯之後就是不
C#編寫一個在asp.net core 3.1下的簡單的corn模式的計劃任務和一個更簡單的定時器類
asp.net core 下,新增了一個BackgroundService用來實現能在後臺跑一個長久執行的任務,因此,也可以用來替換掉原來使用的static的Timer元件, Timer元件主要有以下幾個麻煩的地方 1.如果是需要長時間跑的定時任務,需要定義為static,,在asp.net core下,無法
C# System.Timers.Timer定時器的使用和定時自動清理內存應用
for process work proc program 指定時間 handle 清理 interval 項目比較大有時候會比較卡,雖然有GC自動清理機制,但是還是有不盡人意的地方。所以嘗試在項目啟動文件中,手動寫了一個定時器,定時清理內存,加快項目運行速度。 pub
自己編寫的 C++ 超輕量級日誌類
生日 輸出時間 hello 默認 include 行數 ble lease std 【自己編寫的 C++ 超輕量級日誌類(兼容vc++6.0、vs2010、vs2015)】 先來看效果: 【測試文件:test.cpp】 /* 作者:閆文山 時間:2017/07/02
C# 定時器傳值問題詳解
ati bll main 實例 詳解 use object handle source //傳參數定時器 private static System.Timers.Timer aTimer; Main(ApprovalID); public static void
Golang中使用heap編寫一個簡單高效的定時器模塊
true pop 邏輯 .com light 初始化 callback before cell 定時器模塊在服務端開發中非常重要,一個高性能的定時器模塊能夠大幅度提升引擎的運行效率。使用Golang和heap實現一個通用的定時器模塊,代碼來自:https://github.
C#多線程學習(五) 多線程的自動管理(定時器)
class 時間 change chan 表示 () 圖片 管理 rda Timer類:設置一個定時器,定時執行用戶指定的函數。 定時器啟動後,系統將自動建立一個新的線程,執行用戶指定的函數。 初始化一個Timer對象: Timer timer
用C#語言編寫:集合管理器
list 管理 main 繼續 console reac 提示 回車 read static void Main(string[] args) { List<int> numbers = new List<int>
C# 定時器 一個簡單 並且可以直接運行的Demo
threading pac als 簡單 time tar model ali 代碼 using System; using System.Collections.Generic; using System.ComponentModel; using System.Dat
c++定時器
異步操作 回調函數 epoll cal name async class a bind posix io_service的任務執行流程:調用run方法,進入主loop;判斷公有隊列是否為空,不為空則取出任務並執行,當任務數大於1時同時喚醒其他空閑線程;任務執行結束,把各個線