zoukankan      html  css  js  c++  java
  • C#固定时间执行指定事件(观察者模式+异步委托)

    最近有个项目需要每天固定的时间去执行指定的事件,发现网上关于这样的文章比较少,而且比较散。通过学习了几篇文章后终于实现了这个功能,在此也特别感谢这些文章的作者们,这也是我第一次在园子里面发文章,望多指教。

    关于观察者模式,我在这里就不做讲解了,如有不懂,可以参考相关文章。

    那么开始入正题。

    主要有三个页面:Observer.cs(观察者)、Subject.cs(通知者)、Form1.cs

    Observer.cs

    复制代码
    class Observer
        {
            /// <summary>
            /// 执行事件A
            /// </summary>
            /// <returns></returns>
            public string DoA()
            {
                return "时间到了,执行事件A~~";
            }
    
            /// <summary>
            ///执行事件B
            /// </summary>
            /// <returns></returns>
            public string DoB()
            {
                return "时间到了,执行事件B~~";
            }
    
        }
    复制代码

    Subject.cs(用于通知观察者的类)

    复制代码
    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的时间间隔设为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");
                //设置固定时间要执行的事件
                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 = "";
                //执行事件
                res += subject.Notify();
                if (res != "")
                {
                    txtShow.AppendText(now + ":");
                    txtShow.AppendText(res);
                    txtShow.AppendText("
    ");
                }
    }
    复制代码

     结果:

    但以上的方法是同步的,也就是第一个方法执行太久的话会影响第二个方法的执行,那么要解决这问题,下面就用到异步委托。

    Observer.cs不用修改到,这也是用了观察者模式所带来的好处。

    Subject.cs(修改了Notify方法,添加了一个委托、事件和方法)

    复制代码
    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())
                    {
                        //异步调用委托,第一个参数为要回调的函数,第二个参数为要向回调函数传入的值
                        //这里传入被调用方法的委托
                        handler.BeginInvoke(CallBack, handler);
                        
                    }
                }
                
            }
    
            /// <summary>
            /// 回调函数
            /// </summary>
            /// <param name="show"></param>
            public void CallBack(IAsyncResult obj)
            {
                EventHandler handler = (EventHandler)obj.AsyncState;
                //获取被调用方法的返回的信息
                string res= handler.EndInvoke(obj);
                ShowInfoEvent(res);
            }
    
        }
    }
    复制代码

    这里稍微解释一下。ShowInfoHandler、ShowInfoEvent用于向主线程txtShow输出提示信息用的,若不用输出提示信息可以省去。(Form1.cs会用到)

    handler.BeginInvoke调用异步委托,第一个参数传入要回调的函数,也就是执行完自身的方法后会继续执行的方法;第二个参数一般传入自身的委托,方便在回调函数中获取执行完返回的信息。

    Form1.cs

    复制代码
     //非主线程无法操作界面的控件,所以用委托来实现向txtShow输出信息
            public void ShowInfo(string info)
            {
                txtShow.Invoke(new Action(()=>{txtShow.AppendText(info+"
    ");}));
            }
    
            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("现在时间:"+now+"
    ");
                        subject.Output += new EventHandler(observer.DoA);
                        
                        break;
                    case "23:21:00":
                        txtShow.AppendText("现在时间:"+now+"
    ");
                        subject.Output += new EventHandler(observer.DoB);
                        break;
                }
                subject.Notify();
                
                
            }
    复制代码

    子线程操作主线程的控件还有其他方法,大家可以尝试下,这里就不整理了。

    结果:

    http://www.cnblogs.com/chenjiguang/p/4271356.html

  • 相关阅读:
    设计模式六大原则【转】
    2进制中1的个数
    最大子数组和
    八皇后问题
    读取tomcat下的文件夹路径
    <![CDATA[ ]]>
    数据库(第一范式,第二范式,第三范式)
    input设置disabled,经过strus2提交到后台,后台取不到值
    下载项目乱码
    jsp与Action值得对应
  • 原文地址:https://www.cnblogs.com/cmblogs/p/6249513.html
Copyright © 2011-2022 走看看