C # fixed-time execution of specified events (Observer mode + asynchronous delegation ),
Recently, a project needs to execute a specified event at a fixed time every day. It is found that there are few such articles on the Internet and they are scattered. After learning a few articles, I finally realized this function. I am also very grateful to the authors of these articles. This is also the first time I have posted an article in the garden.
I will not explain the observer mode here. If you do not understand it, refer to the relevant articles.
Start to get started.
There are three main pages: Observer. cs (Observer), Subject. cs (notifier), Form1.cs
Observer. cs
Class Observer {// <summary> // execute event A // </summary> /// <returns> </returns> public string DoA () {return "Time is up. Execute event ~~ ";}/// <Summary> /// execute Event B /// </summary> /// <returns> </returns> public string DoB () {return "Time is up. Execute Event B ~~ ";}}
Subject. cs (class used to notify the observer)
Namespace XXXXXX {// declare delegate string EventHandler (); class Subject {// declare event public event EventHandler Output; public string Policy () {string res = ""; if (Output! = Null) {res = Output ();} return res ;}}}
Form1.cs
The TextBox controls txtShow and Timer controls are used. The timer interval is set to 1 s.
Private void timer_Tick (object sender, EventArgs e) {Subject subject = new Subject (); Observer observer Observer = new Observer (); string now = DateTime. now. toString ("HH: mm: ss"); // set the switch (now) {case "22:28:00": subject to be executed at a fixed time. output + = new EventHandler (observer. doA); break; case "22:29:00": subject. output + = new EventHandler (observer. doB); break;} string res = ""; // execute the event res + = subject. notify (); I F (res! = "") {TxtShow. AppendText (now + ":"); txtShow. AppendText (res); txtShow. AppendText ("\ r \ n ");}
}
Result:
However, the preceding method is synchronous, that is, if the first method is executed for too long, the execution of the second method will be affected. To solve this problem, asynchronous delegation is used below.
Observer. cs does not need to be modified, which is also a benefit of the Observer mode.
Subject. cs (modified the delegate y method and added a delegate, event, and method)
Namespace XXXX {// declare delegate string EventHandler (); delegate void ShowInfoHandler (string info); class Subject {// declare the event public event EventHandler Output; public event ShowInfoHandler ShowInfoEvent; public void every Y () {if (Output! = Null) {foreach (EventHandler handler in Output. getInvocationList () {// call the delegate asynchronously. The first parameter is the function to be called back, the second parameter is the value to be passed in to the callback function. // here, the delegate handler of the called method is passed in. beginInvoke (CallBack, handler );}}} /// <summary> /// CallBack function /// </summary> /// <param name = "show"> </param> public void CallBack (IAsyncResult obj) {EventHandler handler = (EventHandler) obj. asyncState; // obtain the information returned by the called method string res = handler. endInvoke (obj); ShowInfoEvent (res );}}}
Here, I will explain it a little. ShowInfoHandler and ShowInfoEvent are used to output the prompt information to the main thread txtShow. You can save it if you do not need to output the prompt information. (Form1.cs will be used)
Handler. beginInvoke calls asynchronous delegation. The first parameter is used to pass in the function to be called back, that is, the method that will continue to be executed after the method is executed. The second parameter is generally used to pass in its own delegate, it is convenient to obtain the information returned after execution in the callback function.
Form1.cs
// The interface control cannot be operated by a non-main thread. Therefore, the delegate is used to output public void ShowInfo (string info) {txtShow to 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 (); // submit the method for outputting information to txtShow to subject's delegate subject. showInfoEvent + = new ShowInfoHandler (ShowInfo); string now = DateTime. now. toString ("HH: mm: ss"); switch (now) {case "23:20:00": txtShow. appendText ("current time:" + now + "\ r \ n"); subject. output + = new EventHandler (observer. doA); break; case "23:21:00": txtShow. appendText ("current time:" + now + "\ r \ n"); subject. output + = new EventHandler (observer. doB); break;} subject. notify ();}
There are other methods for the sub-thread to operate the control of the main thread. You can try it and we will not sort it out here.
Result: