C# Timer用法有哪些呢?我们在使用C# Timer时都会有自己的一些总结,那么这里向你介绍3种方法,希望对你了解和学习C# Timer使用的方法有所帮助。
关于C# Timer类 在C#里关于定时器类就有3个
C# Timer使用的方法1.定义在System.Windows.Forms里
C# Timer使用的方法2.定义在System.Threading.Timer类里 "
C# Timer使用的方法3.定义在System.Timers.Timer类里
下面我们来具体看看这3种C# Timer用法的解释:
◆System.Windows.Forms.Timer
应用于WinForm中的,它是通过Windows消息机制实现的,类似于VB或Delphi中的Timer控件,内部使用API SetTimer实现的。它的主要缺点是计时不精确,而且必须有消息循环,Console Application(控制台应用程序)无法使用。
◆System.Timers.Timer
和System.Threading.Timer非常类似,它们是通过.NET Thread Pool实现的,轻量,计时精确,对应用程序、消息没有特别的要求。
◆System.Timers.Timer还可以应用于WinForm,完全取代上面的Timer控件。它们的缺点是不支持直接的拖放,需要手工编码。
//实例化Timer类,设置间隔时间为10000毫秒; System.Timers.Timer t = new System.Timers.Timer(1000); //到达时间的时候执行注册事件 t.Elapsed += (obj,e) => { Console.WriteLine("ok"); }; //设置是执行一次(false)还是一直执行(true); t.AutoReset = true; //是否执行System.Timers.Timer.Elapsed注册事件; t.Enabled = true; Console.ReadKey();
javascript 对应的
setInterval(funciont(){xxxxx},1000)一直执行
setTimeout(function(){xxxxx},1000)只执行一次
需求:规定时间启动定时器(比如早上下午6点启动,上午就管理员运行程序 )
code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Threading; namespace CsDemo { class Program { static System.Timers.Timer t = null; static Thread td = null; static bool isOpenTimers = false; static bool isThreadFalg = true; static void Main(string[] args) { Timers(statrDay() * msecTime);//statrDay() * msecTime读取配置文件或者指定时间 Threads(); } private static void Threads() { td = new Thread(ThreadMethod); td.IsBackground = true; td.Start(td); } /// <summary>定时器 /// </summary> public static void Timers(double Time) { t = new System.Timers.Timer(Time); t.Elapsed += (obj, e) => { //Do something }; t.AutoReset = true; t.Enabled = true; } /// <summary>线程 指定时间启动定时器 /// </summary> private static void ThreadMethod(object td) { var temp = td as Thread; while (isThreadFalg) { int hour = DateTime.Now.Hour; if (hour >= hourTime)//hourTime 读取配置文件 下午6点 { if (!isOpenTimers) { t.Start(); Thread.Sleep(1000); temp.Abort(); } } Thread.Sleep(300000); } } } }
2:问题 定时器里面方法没有执行完 下一次又启动了 但是我希望排队的方式运行 (上次任务结束才开始)
code:
/// <summary>定时器 /// </summary> public static void Timers(double Time) { t = new System.Timers.Timer(Time); t.Elapsed += (obj, e) => { t.Stop(); //Do something t.Start(); }; t.AutoReset = true; t.Enabled = true; t.Start(); }
3:需求3 假设定时器7天运行一次 1号开启 突然bug或者意外3号天挂了 第4天开启 这个时候 7号继续执行 不能等到4+7 11号执行
原理:
每次运行定时器动态计算时间:异常时候写入奔溃时间
1:
Timers(statrDay() * msecTime);//mescTime 为 86400000 一天 这样项目原因不考虑
public double statrDay() { DateTime lastDay = DateTime.Parse(nextDayStar); TimeSpan ts = lastDay - DateTime.Now; var dayTemp = ts.Days; if (dayTemp >= pushTime || dayTemp <= 0) dayTemp = pushTime; return dayTemp; }
2:Timer Elapsed方法每次运行写入下次启动时间
Logging.GetInstance().InsertNextDayStart(DateTime.Now.AddDays(pushTime).ToString());pushTime=7
3:程序奔溃写入下次启动时间
public static void InsertLog() { ThreadPool.QueueUserWorkItem(o => { while (true) { try { if (tempLog.Count > 0) { string errorMsg = tempLog.Dequeue(); Logging.GetInstance().WriteLog(errorMsg, path); Logging.GetInstance().InsertNextDayStart(DateTime.Now.AddDays(frm.pushTime).ToString()); Thread.Sleep(30); } else { Thread.Sleep(30000); } } catch (Exception ex) { tempLog.Enqueue("系统错误" + GetExceptionMsg(ex as Exception, ex.ToString())); } } }); }
为队列 public static Queue<string> tempLog = new Queue<string>();
详细代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using DAL; using Redslide.HttpLib; using System.Web; using System.Threading; using System.Collections.Concurrent; using System.Reflection; using System.Threading.Tasks; using Tool.Entity; using System.Diagnostics; using System.Configuration; using System.IO; using System.Web.Script.Serialization; namespace IllegalMsgPush { public partial class frWz : Form { #region 全局变量 System.Timers.Timer t = null; Thread td = null; bool isOpenTimers = false; bool isThreadFalg = true; string urlCopy = null; ConcurrentDictionary<string, userList> dicUser=null; static Task tk = null; /// <summary> /// 违章消息推送时间启动(单位小时) /// </summary> public int hourTime = 0; /// <summary> /// 违章消息推送定时推送(单位天) /// </summary> public int pushTime = 0; /// <summary> /// 下次启动时间(day) /// </summary> public string nextDayStar =null; Action<string> acCarMsgShow = null; public int holdID; public int msecTime; /// <summary>同步锁用于删除队列信息与添加消息 /// </summary> private static object _objfrWzMsgLock = new object(); #endregion public frWz() { InitializeComponent(); this.SizeChanged += (o, e) => { if (this.WindowState == FormWindowState.Minimized) { this.Hide(); this.notifyIcon1.Visible = true; } }; InitializationParameter(); Timers(statrDay() * msecTime); Threads(); } #region -sql command /// <summary>用户以及子用户下面的车 /// </summary> private DataTable LoadCarChildList() { var sql = string.Format(@"with cte as ( select userName ,userID from std_UserInfo where isDeleted=0 ) select a.ObjectID,a.vehicleNum,d.EngineCode,d.ShelfCode ,c.userName from dbo.Table_F_GetObjectInfoByObjUserHoldID(0,1,1) a left join std_ObjAppend d with (nolock) on a.ObjectID=d.ObjectID left join std_UserObj b with (nolock) on d.ObjectID=b.ObjectID left hash join cte c on b.userID=c.userID where c.userName is not null", holdID); return SqlHelper.ExecuteDataset(sql).Tables[0]; } public void InsertPushInfo(string objectID, string vehclieNum, string userName) { Task.WaitAll(tk); StringBuilder sql = new StringBuilder(); var temp = objectID + "_" + userName; if (ContainsKey(temp)) { sql.Append(@"INSERT INTO personal_PushInfo (Contype,context,UserName,OBDTerminalNo ,voiceName ,isDeleted ,RcvTime ,TypeID ,ID ,VehicleNum ,ItemID,voiceDetail,GPSTime ,CerFileName ,CerPassword,PushServerType) "); sql.AppendFormat(@"VALUES('违章','您有一条新的违章消息','{0}','{1}','109.wav' ,0,getdate(),2,'{2}','{3}' ,109,'您有一条新的违章消息',getdate(),'{4}' ,'{5}',1)" , dicUser[temp].UserName //UserName , dicUser[temp].OBDTerminalNo //OBDTerminalNo , int.Parse(objectID) //ID -车辆ID ObjectID , vehclieNum //VehicleNum , dicUser[temp].CerFileName //CerFileName 安卓null , dicUser[temp].CerPassword //CerPassword ); SqlHelper.ExecuteNonQuery(sql.ToString()); } else { string str = "key不存在异常出现在ID: " + objectID + "车牌:" + vehclieNum + "userName:" + userName; Logging.GetInstance().WriteLog(str, Program.carListLog); } } public void LoadUserList() { dicUser = new ConcurrentDictionary<string, userList>(); tk = Task.Factory.StartNew(() => { var sql = "SELECT UserName,OBDTerminalNo,ObjectID,CerFileName,CerPassword FROM std_UserObj a left hash join std_UserInfo b on a.UserID=b.UserID WHERE b.isDeleted=0"; var temp = SqlHelper.ExecuteDataset(sql).Tables[0]; if (temp != null || temp.Rows.Count > 0) { var dataType = typeof(userList); var infos = dataType.GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (DataRow row in temp.Rows.AsParallel()) { var obj = (userList)Activator.CreateInstance(dataType); foreach (DataColumn col in temp.Columns.AsParallel()) { try { foreach (PropertyInfo info in infos) { if (info.Name.ToLower() == col.ColumnName.ToLower()) { if (row[col].GetType().FullName != "System.DBNull") { info.FastSetValue(obj, row[col]); } } } } catch { } } Add(obj.ObjectID.ToString() + "_" + obj.UserName, obj); } } }); } public void csDemo() { if (this.txtContent.InvokeRequired) { this.txtContent.Invoke(acCarMsgShow, "执行一次"); } string str = @"INSERT INTO personal_PushInfo(Contype,context,UserName,OBDTerminalNo ,voiceName ,isDeleted ,RcvTime ,TypeID ,ID ,VehicleNum ,ItemID ,voiceDetail,GPSTime ,CerFileName ,CerPassword,PushServerType) VALUES('报警','车辆设防','chen','d3e0d773cd1dde1a939bde8b4ea5605ffb0a9aa3dd07be1dbb8213f6f7b64862','79.wav' ,0,getdate(),1,73252,'粤Blyq' , 79,'您有一条新的违章消息',getdate(),'carGeniusP_erp_dev.pem' ,'123456',0)"; SqlHelper.ExecuteNonQuery(str); } #endregion private void HttpGet() { var dt = LoadCarChildList(); if (dt == null || dt.Rows.Count == 0) return; JavaScriptSerializer js = new JavaScriptSerializer(); foreach (DataRow item in dt.Rows) { lock (_objfrWzMsgLock) { var carCode = item["EngineCode"].ToString(); if (string.IsNullOrEmpty(carCode)) continue; var carNumber = item["ShelfCode"].ToString(); if (string.IsNullOrEmpty(carNumber)) continue; var objectID = item["ObjectID"].ToString(); var vehclieNum = item["vehicleNum"].ToString(); var userName = item["userName"].ToString(); string url = string.Format(urlCopy, HttpUtility.UrlEncode(vehclieNum, System.Text.Encoding.UTF8), GetLastStr(carCode, 6), GetLastStr(carNumber, 6)); Request.Get(url, null, result => { var json = (Dictionary<string, object>)js.DeserializeObject(result); if (json == null) return; if (bool.Parse(json["Success"].ToString()) && bool.Parse(json["HasData"].ToString())) { var tempMsg = "车牌ID:" + objectID + "--车牌号:" + vehclieNum + "--用户名:" + userName; if (this.txtContent.InvokeRequired) this.txtContent.Invoke(acCarMsgShow, tempMsg); InsertPushInfo(objectID, vehclieNum, userName); Logging.GetInstance().WriteLog(tempMsg, Program.carListLog); } else { Logging.GetInstance().WriteLog(result.ToString(), Program.carListLog); } }, e => { string str = "http请求错误" + Program.GetExceptionMsg(e, string.Empty); Logging.GetInstance().WriteLog(str, Program.carListLog); }); } } } #region event private void button1_Click(object sender, EventArgs e) { if (MessageBox.Show("要重新启动嘛?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { t = null; td = null; notifyIcon1 = null; Application.Restart(); } } private void frWz__Shown(object sender, EventArgs e) { this.Visible = true; notifyIcon1.Visible = true; notifyIcon1.Icon = this.Icon; } private void frWz_FormClosing(object sender, FormClosingEventArgs e) { if (notifyIcon1 != null) { e.Cancel = true; this.Visible = false; } } private void ToolStripMenuItem_Show_Click(object sender, EventArgs e) { this.Show(); this.WindowState = FormWindowState.Normal; } private void ToolStripMenuItem_Exit_Click(object sender, EventArgs e) { if (MessageBox.Show("你确定退出吗?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { t = null; td = null; dicUser = null; notifyIcon1 = null; this.Close(); } } private void notifyIcon1_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { notifyIcon1.Visible = true; this.Show(); this.WindowState = FormWindowState.Normal; } else { Point pt = new Point(); pt = Control.MousePosition; contextMenuStrip1.Show(pt); } } #endregion private void Threads() { td = new Thread(ThreadMethod); td.IsBackground = true; td.Start(td); } /// <summary>定时器 /// </summary> public void Timers(double Time) { t = new System.Timers.Timer(Time); t.Elapsed += (obj, e) => { t.Stop(); Logging.GetInstance().InsertNextDayStart(DateTime.Now.AddDays(pushTime).ToString()); isOpenTimers = true; LoadUserList(); HttpGet(); t.Interval = pushTime * msecTime; t.Start(); }; t.AutoReset = true; t.Enabled = true; } /// <summary>初始化参数和变量 /// </summary> private void InitializationParameter() { Logging.GetInstance().CreateFile(Program.path, Program.carListLog); urlCopy = ConfigRead.GetInstance().pushUrlValue(); hourTime = ConfigRead.GetInstance().hourTimeValue(); pushTime = ConfigRead.GetInstance().pushDayValue(); nextDayStar = Logging.GetInstance().ReadNextDayStart(); holdID = ConfigRead.GetInstance().holdIDValue(); msecTime = ConfigRead.GetInstance().msecTimeValue(); acCarMsgShow = (strMsg) => { txtContent.AppendText("请求成功消息:" + strMsg + "\r\n"); }; } /// <summary>线程 指定时间启动定时器 /// </summary> private void ThreadMethod(object td) { var temp = td as Thread; while (isThreadFalg) { int hour = DateTime.Now.Hour; if (hour >= hourTime) { if (!isOpenTimers) { t.Start(); Thread.Sleep(1000); temp.Abort(); } } Thread.Sleep(300000); } } #region IDictionary<string,ResultType> 成员 public void Add(string key, userList value) { dicUser.TryAdd(key, value); } public bool ContainsKey(string key) { return dicUser.ContainsKey(key); } public ICollection<string> Keys { get { return dicUser.Keys; } } public bool Remove(string key) { userList val; return dicUser.TryRemove(key, out val); } public bool TryGetValue(string key, out userList value) { return dicUser.TryGetValue(key, out value); } public ICollection<userList> Values { get { return dicUser.Values; } } public userList this[string key] { get { return dicUser[key]; } set { dicUser[key] = value; } } #endregion public void updateConfig(string key, string value) { var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); if (config.AppSettings.Settings[key] != null) { config.AppSettings.Settings[key].Value = value; } else { config.AppSettings.Settings.Add(key, value); } config.Save(ConfigurationSaveMode.Modified); ConfigurationManager.RefreshSection("appSettings"); } public double statrDay() { DateTime lastDay = DateTime.Parse(nextDayStar); TimeSpan ts = lastDay - DateTime.Now; var dayTemp = ts.Days; if (dayTemp >= pushTime || dayTemp <= 0) dayTemp = pushTime; return dayTemp; } public string GetLastStr(string str, int num) { if (str.Length > num) { str = str.Substring(str.Length - num, num); } return str; } } public class userList { public string UserName { get; set; } public string OBDTerminalNo { get; set; } public int ObjectID { get; set; } public string CerPassword { get; set; } public string CerFileName { get; set; } } }
Program
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using System.Text; using Tool.Entity; using System.Diagnostics; using System.Threading; using System.IO; using System.Collections; namespace IllegalMsgPush { static class Program { public static frWz frm = null; public static string path = ""; public static string carListLog = ""; public static Queue<string> tempLog = new Queue<string>(); /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { #region 应用程序的主入口点 try { bool flag; Mutex mutex = new Mutex(true, Application.ProductName, out flag); if (flag) { path = string.Format("{0}{1}", AppDomain.CurrentDomain.BaseDirectory, @"/log/"); carListLog = string.Format("{0}{1}", AppDomain.CurrentDomain.BaseDirectory, @"/carListLog/"); InsertLog(); //设置应用程序处理异常方式:ThreadException处理 Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); //处理UI线程异常 Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); //处理非UI线程异常 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); frm = new frWz(); Application.Run(frm); //释放 System.Threading.Mutex 一次 mutex.ReleaseMutex(); } else { MessageBox.Show(null, "相同的程序已经在运行了,请不要同时运行多个程序!\n\n这个程序即将退出!", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning); Application.Exit(); } } catch (Exception ex) { string str = "系统错误" + GetExceptionMsg(ex, string.Empty); tempLog.Enqueue(str); } #endregion } static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) { string str = "系统错误" + GetExceptionMsg(e.Exception, e.ToString()); tempLog.Enqueue(str); } static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { string str = "系统错误" + GetExceptionMsg(e.ExceptionObject as Exception, e.ToString()); tempLog.Enqueue(str); } public static string GetExceptionMsg(Exception ex, string backStr) { StringBuilder sb = new StringBuilder(); sb.AppendLine("****************************异常文本****************************"); sb.AppendLine("【出现时间】:" + DateTime.Now.ToString()); if (ex != null) { sb.AppendLine("【异常类型】:" + ex.GetType().Name); sb.AppendLine("【异常信息】:" + ex.Message); sb.AppendLine("【堆栈调用】:" + ex.StackTrace); } else { sb.AppendLine("【未处理异常】:" + backStr); } sb.AppendLine("***************************************************************"); return sb.ToString(); } public static void InsertLog() { ThreadPool.QueueUserWorkItem(o => { while (true) { try { if (tempLog.Count > 0) { string errorMsg = tempLog.Dequeue(); Logging.GetInstance().WriteLog(errorMsg, path); Logging.GetInstance().InsertNextDayStart(DateTime.Now.AddDays(frm.pushTime).ToString()); Thread.Sleep(30); } else { Thread.Sleep(30000); } } catch (Exception ex) { tempLog.Enqueue("系统错误" + GetExceptionMsg(ex as Exception, ex.ToString())); } } }); } } }
配置文件:
<?xml version="1.0"?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup> <appSettings> <!--路精灵所属单位ID配置 start--> <add key="holdID" value="1"/> <!--路精灵所属单位ID配置end--> <!--违章消息推送时间天数start (正整数)--> <add key="pushDay" value="14"/> <!--违章消息推送时间天数end (正整数)--> <!--违章消息推送几点启动start (正整数0-24)--> <add key="hourTime" value="6"/> <!--违章消息推送几点启动结束end (正整数)--> <!--违章消息URL start--> <add key="pushUrl" value="xxxx"/> <!--违章消息URL end--> <!--违章消息推送毫秒 (默认86400000 测试可调整修改)--> <add key="msecTime" value="86400000"/> <!--违章消息推送毫秒end (正整数)--> </appSettings> <connectionStrings> <!--数据库连接串开始--> <add name="ConnStr" connectionString="xxxxx"/> <!--数据库连接串结束--> </connectionStrings> </configuration>