1. 程式人生 > >C#自己編寫定時器

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時同時喚醒其他空閑線程;任務執行結束,把各個線