代码改变世界

Effective C# 学习笔记(二十五)以事件机制来实现通知

2011-07-15 19:35  小郝(Kaibo Hao)  阅读(323)  评论(0编辑  收藏  举报

事件是用来通知观察者来进行相应的操作,其经常被用来在事件的发送者和接受者间进行解耦,事件的机制也是用观察者模式来实现的。下面是一组事件参数(LoggerEventArgs)和定义事件属性类(Logger类中定义了Log事件)的代码:

public class LoggerEventArgs : EventArgs

{

public string Message { get; private set; }

public int Priority { get; private set; }

public LoggerEventArgs(int p, string m)

{

Priority = p;

Message = m;

}

}

public class Logger

{

static Logger()

{

theOnly = new Logger();

}

private Logger()

{

}

private static Logger theOnly = null;

public static Logger Singleton

{

get { return theOnly; }

}

// Define the event:

public event EventHandler<LoggerEventArgs> Log;

/* 上面事件的定义其实可以解析为下面的代码

 private EventHandler<LoggerEventArgs> log;

  public event EventHandler<LoggerEventArgs> Log

 {

      add { log = log + value; }

      remove { log = log - value; }

 }

*/

// add a message, and log it.

public void AddMsg(int priority, string msg)

{

// 这里构建了一个临时变量来缓存事件的引用,没有直接引用Log事件引用,这样在多线程调用中就不会出现在调用前,Log事件被其他线程去除的冲突问题

EventHandler<LoggerEventArgs> l = Log;

if (l != null)

l(this, new LoggerEventArgs(priority, msg));

}

}

自定义一个多系统事件统一处理类

public class Logger

{

//利用Dictionary<string,T>范型集合来构建键值对形式(系统名称,事件委托声明)的事件集合,这里的T是EventHandler<LoggerEventArgs>的事件类型

        private static Dictionary<string, EventHandler<LoggerEventArgs>> Handlers =

            new Dictionary<string, EventHandler<LoggerEventArgs>>();

        /// <summary>

        /// 添加日志事件

        /// </summary>

        /// <param name="system">系统名称</param>

        /// <param name="ev">事件声明</param>

        static public void AddLogger(string system, EventHandler<LoggerEventArgs> ev)

        {

            if (Handlers.ContainsKey(system))

                Handlers[system] += ev;

            else

                Handlers.Add(system, ev);

        }

        /// <summary>

        /// 移除日志事件

        /// </summary>

        /// <param name="system">系统名称</param>

        /// <param name="ev">事件声明</param>

        static public void RemoveLogger(string system,EventHandler<LoggerEventArgs> ev)

        {

            // will throw exception if system

            // does not contain a handler.

            Handlers[system] -= ev;

        }

        /// <summary>

        /// 添加日志信息

        /// </summary>

        /// <param name="system">系统名称</param>

        /// <param name="priority">优先级</param>

        /// <param name="msg">消息名称</param>

        static public void AddMsg(string system,int priority, string msg)

        {

            if (string.IsNullOrEmpty(system))

            {

                EventHandler<LoggerEventArgs> l = null;

                Handlers.TryGetValue(system, out l);

                LoggerEventArgs args = new LoggerEventArgs(priority, msg);

                if (l != null)

                    l(null, args);

                // The empty string means receive all message

                l = Handlers[""] as EventHandler<LoggerEventArgs>;

                if (l != null)

                    l(null, args);

            }

        }

}