现在的位置: 首页 > 综合 > 正文

C# 中多事件类型

2012年07月31日 ⁄ 综合 ⁄ 共 4141字 ⁄ 字号 评论关闭

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace NET.MST.Sixth.MultiEventsClass
{
    class MainClass
    {
        static void Main(string[] args)
        {
            //测试事件的触发
            using (MultiEventsClass c = new MultiEventsClass())
            {
                Customer customer = new Customer(c);
                c.RiseEvent1();
                c.RiseEvent2();
            }
            Console.Read();
        }
    }

    /// <summary>
    /// 多事件类型
    /// </summary>
    public partial class MultiEventsClass:IDisposable
    {
        /// <summary>
        /// System.ComponentModel.EventHandlerList包含了一个委托链表的容器
        /// 实现了多事件存放在一个容器之中的包装
        /// EventHandlerList使用的是链表数据结构
        /// </summary>
        private EventHandlerList _events;
       
        //公共构造方法
        public MultiEventsClass()
        {
            _events = new EventHandlerList();
        }
        /// <summary>
        /// 释放EventHanlderList
        /// </summary>
        public void Dispose()
        {
            _events.Dispose();
        }
    }
    /// <summary>
    /// 多事件类型
    /// </summary>
    public partial class MultiEventsClass : IDisposable
    {
        //下面为每一个需要实现的事件申明委托类型、订阅和取消定语方法、事件在集合中的键和触发事件方法
        //这样的定义和实际申明一个事件成员不同,这样做不会在一个新的MultiEventsClass中分配所有的事件委托链表的内存空间
        //这就是提高性能的关键
        //申明事件1
        #region event1
        //事件1的委托原型
        public delegate void Event1Handler(Object sender, EventArgs e);
        //这里是静态的字段,有效提高性能
        protected static readonly Object Event1Key = new object();       
        /// <summary>
        /// 一组订阅、取消订阅事件的方法
        /// 注意EventHandlerList并不提供线程同步,所以在add和remove方法前加上线程同步属性
        /// 读者可以采取lock机制来代替
        /// </summary>
        public event Event1Handler Event1
        {
            [MethodImpl(MethodImplOptions.Synchronized)]
            add
            {
                _events.AddHandler(Event1Key, value);
            }
            [MethodImpl(MethodImplOptions.Synchronized)]
            remove
            {
                _events.RemoveHandler(Event1Key, value);
            }
        }
        /// <summary>
        /// 触发事件1
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnEvent1(EventArgs e)
        {
            _events[Event1Key].DynamicInvoke(this, e);
        }
        /// <summary>
        /// 这个方法简单地触发事件1,以便于测试
        /// </summary>
        public void RiseEvent1()
        {
            OnEvent1(EventArgs.Empty);
        }
        #endregion
        //申明事件2
        #region event2
        //事件2的委托原型
        public delegate void Event2Handler(Object sender, EventArgs e);
        //这里是静态的字段,有效提高性能
        protected static readonly Object Event2Key = new object();
        /// <summary>
        /// 一组订阅、取消订阅事件的方法
        /// 注意EventHandlerList并不提供线程同步,所以在add和remove方法前加上线程同步属性
        /// 读者可以采取lock机制来代替
        /// </summary>
        public event Event2Handler Event2
        {
            [MethodImpl(MethodImplOptions.Synchronized)]
            add
            {
                _events.AddHandler(Event2Key, value);
            }
            [MethodImpl(MethodImplOptions.Synchronized)]
            remove
            {
                _events.RemoveHandler(Event2Key, value);
            }
        }
        /// <summary>
        /// 触发事件2
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnEvent2(EventArgs e)
        {
            _events[Event2Key].DynamicInvoke(this, e);
        }
        /// <summary>
        /// 这个方法简单地触发事件2,以便于测试
        /// </summary>
        public void RiseEvent2()
        {
            OnEvent2(EventArgs.Empty);
        }
        #endregion    
    }

    /// <summary>
    /// 构造一个订阅事件的类型
    /// </summary>
    public class Customer
    {
        public Customer(MultiEventsClass events)
        {
            //订阅事件1
            events.Event1 += Event1Handler;
            //订阅事件2
            events.Event2 += Event2Handler;
        }
        /// <summary>
        /// 事件1回调方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void Event1Handler(object sender, EventArgs args)
        {
            Console.WriteLine("事件1触发");
        }
        /// <summary>
        /// 事件2回调方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void Event2Handler(object sender, EventArgs args)
        {
            Console.WriteLine("事件2触发");
        }
    }
}

抱歉!评论已关闭.