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:
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.Data; usingSystem.Threading; namespaceCsDemo { classProgram { 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 voidThreads() { td = newThread(ThreadMethod); td.IsBackground = true; td.Start(td); } /// <summary>定时器 /// </summary> public static void Timers(doubleTime) { t = newSystem.Timers.Timer(Time); t.Elapsed += (obj, e) =>{ //Do something }; t.AutoReset = true; t.Enabled = true; } /// <summary>线程 指定时间启动定时器 /// </summary> private static void ThreadMethod(objecttd) { var temp = td asThread; 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(doubleTime) { t = newSystem.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 doublestatrDay() { DateTime lastDay =DateTime.Parse(nextDayStar); TimeSpan ts = lastDay -DateTime.Now; var dayTemp =ts.Days; if (dayTemp >= pushTime || dayTemp <= 0) dayTemp =pushTime; returndayTemp; }
2:TimerElapsed方法每次运行写入下次启动时间
Logging.GetInstance().InsertNextDayStart(DateTime.Now.AddDays(pushTime).ToString());pushTime=7
3:程序奔溃写入下次启动时间
public static voidInsertLog() { 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 asException, ex.ToString())); } } }); }
为队列 public static Queue<string> tempLog = new Queue<string>();
详细代码:
usingSystem; usingSystem.Collections.Generic; usingSystem.ComponentModel; usingSystem.Data; usingSystem.Drawing; usingSystem.Linq; usingSystem.Text; usingSystem.Windows.Forms; usingDAL; usingRedslide.HttpLib; usingSystem.Web; usingSystem.Threading; usingSystem.Collections.Concurrent; usingSystem.Reflection; usingSystem.Threading.Tasks; usingTool.Entity; usingSystem.Diagnostics; usingSystem.Configuration; usingSystem.IO; usingSystem.Web.Script.Serialization; namespaceIllegalMsgPush { public partial classfrWz : 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 intholdID; public intmsecTime; /// <summary>同步锁用于删除队列信息与添加消息 /// </summary> private static object _objfrWzMsgLock = new object(); #endregion publicfrWz() { 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> privateDataTable 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, stringuserName) { Task.WaitAll(tk); StringBuilder sql = newStringBuilder(); 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 voidLoadUserList() { 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 intemp.Rows.AsParallel()) { var obj =(userList)Activator.CreateInstance(dataType); foreach (DataColumn col intemp.Columns.AsParallel()) { try{ foreach (PropertyInfo info ininfos) { 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 voidcsDemo() { 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 voidHttpGet() { var dt =LoadCarChildList(); if (dt == null || dt.Rows.Count == 0) return; JavaScriptSerializer js = newJavaScriptSerializer(); foreach (DataRow item indt.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(objectsender, EventArgs e) { if (MessageBox.Show("要重新启动嘛?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==DialogResult.Yes) { t = null; td = null; notifyIcon1 = null; Application.Restart(); } } private void frWz__Shown(objectsender, EventArgs e) { this.Visible = true; notifyIcon1.Visible = true; notifyIcon1.Icon = this.Icon; } private void frWz_FormClosing(objectsender, FormClosingEventArgs e) { if (notifyIcon1 != null) { e.Cancel = true; this.Visible = false; } } private void ToolStripMenuItem_Show_Click(objectsender, EventArgs e) { this.Show(); this.WindowState =FormWindowState.Normal; } private void ToolStripMenuItem_Exit_Click(objectsender, 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(objectsender, MouseEventArgs e) { if (e.Button ==MouseButtons.Left) { notifyIcon1.Visible = true; this.Show(); this.WindowState =FormWindowState.Normal; } else{ Point pt = newPoint(); pt =Control.MousePosition; contextMenuStrip1.Show(pt); } } #endregion private voidThreads() { td = newThread(ThreadMethod); td.IsBackground = true; td.Start(td); } /// <summary>定时器 /// </summary> public void Timers(doubleTime) { t = newSystem.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 voidInitializationParameter() { 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(objecttd) { var temp = td asThread; 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(stringkey, userList value) { dicUser.TryAdd(key, value); } public bool ContainsKey(stringkey) { returndicUser.ContainsKey(key); } public ICollection<string>Keys { get { returndicUser.Keys; } } public bool Remove(stringkey) { userList val; return dicUser.TryRemove(key, outval); } public bool TryGetValue(string key, outuserList value) { return dicUser.TryGetValue(key, outvalue); } public ICollection<userList>Values { get { returndicUser.Values; } } public userList this[stringkey] { get{ returndicUser[key]; } set{ dicUser[key] =value; } } #endregion public void updateConfig(string key, stringvalue) { 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 doublestatrDay() { DateTime lastDay =DateTime.Parse(nextDayStar); TimeSpan ts = lastDay -DateTime.Now; var dayTemp =ts.Days; if (dayTemp >= pushTime || dayTemp <= 0) dayTemp =pushTime; returndayTemp; } public string GetLastStr(string str, intnum) { if (str.Length >num) { str = str.Substring(str.Length -num, num); } returnstr; } } public classuserList { 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
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Windows.Forms; usingSystem.Text; usingTool.Entity; usingSystem.Diagnostics; usingSystem.Threading; usingSystem.IO; usingSystem.Collections; namespaceIllegalMsgPush { static classProgram { 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 voidMain() { #region 应用程序的主入口点 try{ boolflag; Mutex mutex = new Mutex(true, Application.ProductName, outflag); 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 += newSystem.Threading.ThreadExceptionEventHandler(Application_ThreadException); //处理非UI线程异常 AppDomain.CurrentDomain.UnhandledException += newUnhandledExceptionEventHandler(CurrentDomain_UnhandledException); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); frm = newfrWz(); 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(objectsender, System.Threading.ThreadExceptionEventArgs e) { string str = "系统错误" +GetExceptionMsg(e.Exception, e.ToString()); tempLog.Enqueue(str); } static void CurrentDomain_UnhandledException(objectsender, UnhandledExceptionEventArgs e) { string str = "系统错误" + GetExceptionMsg(e.ExceptionObject asException, e.ToString()); tempLog.Enqueue(str); } public static string GetExceptionMsg(Exception ex, stringbackStr) { StringBuilder sb = newStringBuilder(); 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("***************************************************************"); returnsb.ToString(); } public static voidInsertLog() { 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 asException, 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>