十三章高级C#技术之事件

1.事件含义

事件 .NET最常用的OOP技术
订阅(subscribe)一个事件:提供代码,事件发生时执行这些代码(事件处理程序)。
单个事件可供多个处理程序订阅。
菜鸟教程之事件event


2.处理事件

    class Program
    {
        //事件
        static int counter = 0;
        static string displayString =
            "This string will apper one letter at a time.";
        static void Main(string[] args)
        {
            Timer myTimer = new Timer(100);
            //ElapsedEventHandler elapsedEventHandler = new ElapsedEventHandler(WriteChar);
            myTimer.Elapsed += new ElapsedEventHandler(WriteChar);
            myTimer.Start();
            System.Threading.Thread.Sleep(200);
            Console.ReadKey();
        }

        private static void WriteChar(object source, ElapsedEventArgs e)
        {
            Console.Write(displayString[counter++ % displayString.Length]);
        }
    }

代码分析

代码分析


3.定义事件

CH13Ex02
Program.cs
    class Program
    {
        static void Main(string[] args)
        {
            Connection myConnection = new Connection();
            Display myDisplay = new Display();
            myConnection.MessageArrived +=
                new MessageHandler(myDisplay.DisplayMessage);//订阅myDisplay.DisplayMessage
            myConnection.Connect();
            System.Threading.Thread.Sleep(200);
            Console.ReadKey();
        }
    }
Connection.cs
    //委托,可以把Connection对象收到的即时消息发送给Display对象。
    public delegate void MessageHandler(string messageText);

    class Connection
    {
        //命名事件,使用event关键字
        //必须指定使用的委托类型
        public event MessageHandler MessageArrived;
        private Timer pollTimer;
        public Connection()
        {
            //注册Elapsed事件的一个事件处理程序
            pollTimer = new Timer(100);
            pollTimer.Elapsed += new ElapsedEventHandler(CheckForMessage);
        }
        public void Connect() => pollTimer.Start();
        public void Disconnect() => pollTimer.Stop();
        private static Random random = new Random();
        private void CheckForMessage(object sender, ElapsedEventArgs e)
        {
            WriteLine("Checking for new message.");
            if((random.Next(9) == 0) && (MessageArrived != null))
            {
                MessageArrived("Hello Mami!");
            }
        }
    }
Display.cs
    class Display
    {
        public void DisplayMessage(string message)
            => WriteLine($"Message arrived: {message}");
    }

1.多用途的事件处理程序

常见两类参数

object source——引发事件的对象的应用
ElapsedEventArgs——由事件传送的参数
使用object类型的原因是:常常为几个不同对象引发几个相同事件使用同一个事件处理程序。
pollTimer.Elapsed += new ElapsedEventHandler(CheckForMessage);
pollTimer对象名称 Elapsed事件名称 +=订阅 委托名称 事件处理程序

//该方法更加通用
//使用as关键字,避免异常,检查null值
public void DisplayMessage(object source, EventArgs e)
{
	WriteLine($"Message arrived from: {(source as Connection).Name}");
	WriteLine($"Message Text: {(e as MessageArrivedEventArgs).Message}");
}

2.EventHandler和泛型EventHandler<T>类型

简化了代码。

一般来说,在定义事件时,最好使用这些委托类型。注意,如果事件不需要事件实参数据,仍然可以使用EventHandler委托类型,只不过要传递EventArgs.Empty作为实参值。

3.返回值和事件处理程序

都是用void
使用其他返回值会出下问题,因为引发给定的事件可能会调用多个事件处理程序。入果这些处理程序都返回一个值,那么不知道该使用哪个返回值
解决:只允许访问由事件处理程序最后返回的那个值,也就是最后一个订阅该事件的处理程序返回的值。
最好使用void 类型的事件处理程序,且避免使用out参数,参数返回的值的源头不清楚

4.匿名方法

anonymous method 匿名方法
纯粹是为用作委托目的而创建的。

connection.MessageArrived += 
	delegate(Connection source, MessageArrivedEventArgs e)
	{
		WriteLine($"Message arrived from: {(source as Connection).Name}");
		WriteLine($"Message Text: {(e as MessageArrivedEventArgs).Message}\n");
	};

运行时发生错误,还未解决

**注意:**如果外部变量占用大量内存,或者使用的资源在其他方面是比较昂贵的,就可能导致内存或性能问题

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值