最近有個(gè)項(xiàng)目需要每天固定的時(shí)間去執(zhí)行指定的事件,發(fā)現(xiàn)網(wǎng)上關(guān)于這樣的文章比較少,而且比較散。通過(guò)學(xué)習(xí)了幾篇文章后終于實(shí)現(xiàn)了這個(gè)功能,在此也特別感謝這些文章的作者們,這也是我第一次在園子里面發(fā)文章,望多指教。
關(guān)于觀(guān)察者模式,我在這里就不做講解了,如有不懂,可以參考相關(guān)文章。
那么開(kāi)始入正題。
主要有三個(gè)頁(yè)面:Observer.cs(觀(guān)察者)、Subject.cs(通知者)、Form1.cs
Observer.cs
class Observer { /// <summary> /// 執(zhí)行事件A /// </summary> /// <returns></returns> public string DoA() { return "時(shí)間到了,執(zhí)行事件A~~"; } /// <summary> ///執(zhí)行事件B /// </summary> /// <returns></returns> public string DoB() { return "時(shí)間到了,執(zhí)行事件B~~"; } }Subject.cs(用于通知觀(guān)察者的類(lèi))
namespace XXXXXX{ //聲明委托 delegate string EventHandler(); class Subject { //聲明事件 public event EventHandler Output; public string Notify() { string res = ""; if (Output != null) { res = Output(); } return res; } }}Form1.cs
使用了TextBox控件txtShow和Timer控件timer,timer的時(shí)間間隔設(shè)為1s
PRivate void timer_Tick(object sender, EventArgs e) { Subject subject = new Subject(); Observer observer = new Observer(); string now = DateTime.Now.ToString("HH:mm:ss"); //設(shè)置固定時(shí)間要執(zhí)行的事件 switch (now) { case "22:28:00": subject.Output += new EventHandler(observer.DoA); break; case "22:29:00": subject.Output += new EventHandler(observer.DoB); break; } string res = ""; //執(zhí)行事件 res += subject.Notify(); if (res != "") { txtShow.AppendText(now + ":"); txtShow.AppendText(res); txtShow.AppendText("/r/n"); }}
結(jié)果:

但以上的方法是同步的,也就是第一個(gè)方法執(zhí)行太久的話(huà)會(huì)影響第二個(gè)方法的執(zhí)行,那么要解決這問(wèn)題,下面就用到異步委托。
Observer.cs不用修改到,這也是用了觀(guān)察者模式所帶來(lái)的好處。
Subject.cs(修改了Notify方法,添加了一個(gè)委托、事件和方法)
namespace XXXX{ //聲明委托 delegate string EventHandler(); delegate void ShowInfoHandler(string info); class Subject { //聲明事件 public event EventHandler Output; public event ShowInfoHandler ShowInfoEvent; public void Notify() { if (Output != null) { foreach(EventHandler handler in Output.GetInvocationList()) { //異步調(diào)用委托,第一個(gè)參數(shù)為要回調(diào)的函數(shù),第二個(gè)參數(shù)為要向回調(diào)函數(shù)傳入的值 //這里傳入被調(diào)用方法的委托 handler.BeginInvoke(CallBack, handler); } } } /// <summary> /// 回調(diào)函數(shù) /// </summary> /// <param name="show"></param> public void CallBack(IAsyncResult obj) { EventHandler handler = (EventHandler)obj.AsyncState; //獲取被調(diào)用方法的返回的信息 string res= handler.EndInvoke(obj); ShowInfoEvent(res); } }}這里稍微解釋一下。ShowInfoHandler、ShowInfoEvent用于向主線(xiàn)程txtShow輸出提示信息用的,若不用輸出提示信息可以省去。(Form1.cs會(huì)用到)
handler.BeginInvoke調(diào)用異步委托,第一個(gè)參數(shù)傳入要回調(diào)的函數(shù),也就是執(zhí)行完自身的方法后會(huì)繼續(xù)執(zhí)行的方法;第二個(gè)參數(shù)一般傳入自身的委托,方便在回調(diào)函數(shù)中獲取執(zhí)行完返回的信息。
Form1.cs
//非主線(xiàn)程無(wú)法操作界面的控件,所以用委托來(lái)實(shí)現(xiàn)向txtShow輸出信息 public void ShowInfo(string info) { txtShow.Invoke(new Action(()=>{txtShow.AppendText(info+"/r/n");})); } private void timer_Tick(object sender, EventArgs e) { Subject subject = new Subject(); Observer observer = new Observer(); //將向txtShow輸出信息的方法交給subject的委托 subject.ShowInfoEvent += new ShowInfoHandler(ShowInfo); string now = DateTime.Now.ToString("HH:mm:ss"); switch (now) { case "23:20:00": txtShow.AppendText("現(xiàn)在時(shí)間:"+now+"/r/n"); subject.Output += new EventHandler(observer.DoA); break; case "23:21:00": txtShow.AppendText("現(xiàn)在時(shí)間:"+now+"/r/n"); subject.Output += new EventHandler(observer.DoB); break; } subject.Notify(); }子線(xiàn)程操作主線(xiàn)程的控件還有其他方法,大家可以嘗試下,這里就不整理了。
結(jié)果:

新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注