• 基础系列之---5.C#委托和事件使用(参考)


    用一个例子来说明事件的使用。

    创建一个简单的类,名为FileWatch,包含事件OnfileChange。该类将检查在执行应用程序的目录(当前目录,通常是项目名/bin/debug)下,是否存在文件test.txt。

    如果文件被删除或创建,都将触发事件。同时提供一个方法MonitorFile以不断地查询该文件。

    方法:

    在创建一个可用事件之前,首先声明一个委托,放在类的外面。
    public delegate void FileWatchEventHandler(object sender,EventArgs e);

    接下来创建类FileWatch。然后声明事件,注意事件的类型即为我们之前定义的委托


    public event FileWatchEventHandler FileWatchEvent;

    现在创建方法OnFileChange(),当调用该方法时将触发事件

    protected virtual void OnFileChange(EventArgs e)
    {
         if (FileWatchEvent!=null)
         {
             FileWatchEvent(this,e);
         }
    }

    最后,创建方法MonitorFile(),

    public void MonitorFile()
    {
        bool bCurrentStatus;
       
        while(true)
        {
             bCurrentStatus = File.Exists("test.txt");
             if (bCurrentStatus != _bLastStatus) //_bLastStatus为私有字段,初始值为false;
             {
                 _bLastStatus = bCurrentStatus;
                 OnFileChange(EventArgs.Empty);
             }

             Thread.Sleep(250);
        }
    }

    完整代码如下:

    using System;
    using System.Threading; 
    using System.IO;      

    namespace Sample.Event

          public delegate void FileWatchEventHandler(object sender, EventArgs e); 

          public class FileWatch
          {
                private bool _bLastStatus = false;
                public FileWatch()
                {
                      //
                      // TODO: 在此处添加构造函数逻辑
                      //
                } 

                public event FileWatchEventHandler FileWatchEvent; 

                protected virtual void OnFileChange(EventArgs e)
                {
                      if (FileWatchEvent != null)
                      {
                           
                            FileWatchEvent(this, e);
                      }
                } 

                public void MonitorFile()
                {
                      bool bCurrentStatus; 

                      while(true)
                      {
                            bCurrentStatus = File.Exists("test.txt");

                            //状态不符,说明文件被删除或重新创建,此时触发事件;
                            if ( bCurrentStatus != _bLastStatus )
                            {
                                  _bLastStatus = bCurrentStatus;
                                  OnFileChange( EventArgs.Empty );
                            } 

                           
                            Thread.Sleep(250);
                      } 

                }
          }
    }


    使用:创建一个Windows应用程序来测试我们之前建立的FileWatch中的事件。首先将刚才创建的项目编译

    ,生成Assembly:FileWatch.dll,然后添加引用。当然直接添加项目引用也可以。然后在Windows应用程

    序中加入命名空间:

    using Sample.Event;

    然后在应用程序类中,定义一个私有字段,类型为我们之前创建的类FileWatch:
    public class frmMain : System.Windows.Forms.Form
          {
                private Sample.Event.FileWatch FileWatchEventSource;

    并在构造函数中实例化该对象;

    public frmMain()
                {
                     
                      InitializeComponent();
                     

                      FileWatchEventSource = new Sample.Event.FileWatch();

    然后将本地方法OnFileChange连接到事件中:

    FileWatchEventSource.FileWatchEvent+=new Sample.Event.FileWatchEventHandler(OnFileChange);

    我们需要调用MonitorFile方法来触发事件。在本例中,我们用线程来控制MonitorFile方法。这样可以在

    应用程序闲置的时候运行该方法以触发事件。

    thrd = new Thread(new ThreadStart(FileWatchEventSource.MonitorFile));
    thrd.Start();

    最后,我们需要知道事件是否被触发,为了记录下事件触发的历史记录,我们在ListBox控件添加触发内

    容。由于事件触发后调用的方法是OnFileChange,因此我们将操作放在该方法里:

    private void OnFileChange(object Sender, EventArgs e)
    {
       listBox.Items.Add(DateTime.Now.ToString()+": 文件发生改变.");
    }

    当触发事件时,EventHanler会传递sender和EventArgs类的引用。EventArgs类通常是在事件源和触发事

    件器之间传递信息。在本例中,没有传递信息,也没有用到EventArgs类。而只是将事件添加到了ListBox

    中。

    运行结果如下:


     

    结论:在C#中使用事件的要点:

    首先,要建立委托,格式为:
    public delegate void 委托名(object sender, EventArgs e);
    注意:委托即C里的函数指针,在事件中由于要传递事件及触发事件的对象的信息,因此参数表是固定的。委托名一般格式是:名字+EnvenHandle。这样取名比较规范。

    然后,建立一个事件字段:
    public event 委托类型 事件名;
    注意:event关键字代表事件,返回类型为委托;

    再定义一个方法,处理事件,再本例中为OnFileChange(EventArgs e)。在该方法中应该调用事件:
    事件名(object ,EventArgs);
    这里object一般为本身,实参应为this,EventArgs应为OnFileChange中传递过来的实参,尤其是要传递事件的值。

    最后还要创建触发事件的方法。例子中为MonitorFile(),在其方法中,当条件满足则调用OnFileChange来达到触发事件的目的。


    在使用事件时,通常要定义两个方法,一个是和事件定义的委托签名一致的方法,在本例中为OnFileChange(Object sender,EventArgs e);

    注意在例子中,窗体类的OnFileChange和事件类的OnFileChange是不同的。后者用于调用事件,前者则用于绑定事件。绑定事件的方法很简单,用+=表示添加事件,-=表示删除事件。
    例子中
    FileWatchEventSource.FileWatchEvent+=new Sample.Event.FileWatchEventHandler(OnFileChange);
    即为添加事件。

    例子中:首先线程启动(thd.Start()),然后调用MonitorFile()方法。引起事件产生,FileWatchEvent产生后,由于我们将事件FileWatchEvent绑定到了OnFileChange()方法上。因而调用本地即窗口类的OnFileChange()方法,从而实现在ListBox中添加信息。

    博文出处:@张逸,感谢!学习了!

  • 相关阅读:
    线程 & 进程 & 协程
    redis入门
    插入排序
    java多线程(7)实现一个线程池
    java多线程(6)模拟排队叫号程序,4个线程都干活并且结果正确
    java多线程(5)模拟排队叫号程序,不能出现交替执行的结果
    java多线程(4)模拟排队叫号程序,不能出现交替执行的结果
    java多线程(3)其实本节和多线程无关,简单的模板设计模式
    java多线程(2)连续重启一个线程报错
    java多线程(1)
  • 原文地址:https://www.cnblogs.com/xushaoxin/p/3202599.html
Copyright © 2020-2023  润新知