事件提供了一种标准的机制来通知监听者。.NET的事件模式使用了事件语法来实现观察者模式。任意数量的客户对象都可以将自己的处理函数注册到事件上,然后处理这些事件。这些客户对象不需要再编译期就给出。时间也不必非要有订阅者才能正常工作。在C#中使用事件可以降低发送者和可能的通知接受者之间的耦合。发送者可以完全独立于接收者进行开发。事件是实现广播类型行为信息的标准方式。 

    下面按照使用场景的不同,简单列举三种事件模式的实现方式:

    . 公共代码部分

       /// <summary>

复制代码
/// 日志参数类
/// </summary>
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;
}
}
复制代码 . 最常用方式 /// <summary> 复制代码
/// 日志类(第一版):最常见的使用方法,适用于单一调用者情况。
/// </summary>
public class Logger
{
/// <summary>
/// 内部事件句柄
/// </summary>
public event EventHandler<LoggerEventArgs> Log;
/// <summary>
/// 内部日志单键实例
/// </summary>
private static Logger theOnly = null;
public static Logger Singleton
{
get { return theOnly; }
} private Logger()
{ } static Logger()
{
theOnly = new Logger();
} /// <summary>
/// 添加日志信息
/// </summary>
/// <param name="priority"></param>
/// <param name="msg"></param>
public void AddMsg(int priority, string msg)
{
// 该临时变量可预防多线程环境中的竞争条件
EventHandler<LoggerEventArgs> l = Log;
// 执行事件方法
if (l != null)
{
l(this, new LoggerEventArgs(priority, msg));
}
}
}
复制代码 . 针对事件数量多的情况 /// <summary> 复制代码
/// 日志类(第二版):适用于包含事件数量非常多的情况,即添加了一个事件容器,避免因多事件导致的设计臃肿。
/// </summary>
public sealed class Logger
{
/// <summary>
/// 事件容器
/// </summary>
private static System.ComponentModel.EventHandlerList Handlers = new System.ComponentModel.EventHandlerList(); /// <summary>
/// 添加事件
/// </summary>
/// <param name="system"></param>
/// <param name="ev"></param>
public static void AddLogger(string system, EventHandler<LoggerEventArgs> ev)
{
Handlers.AddHandler(system, ev);
} /// <summary>
/// 清除事件
/// </summary>
/// <param name="system"></param>
/// <param name="ev"></param>
public static void RemoveLogger(string system, EventHandler<LoggerEventArgs> ev)
{
Handlers.RemoveHandler(system, ev);
} /// <summary>
/// 添加日志信息
/// </summary>
/// <param name="system"></param>
/// <param name="priority"></param>
/// <param name="msg"></param>
public static void AddMsg(string system, int priority, string msg)
{
if (!string.IsNullOrEmpty(system))
{
// 根据key获取相应的事件
EventHandler<LoggerEventArgs> l = Handlers[system] as EventHandler<LoggerEventArgs>;
// 事件参数
LoggerEventArgs args = new LoggerEventArgs(priority, msg);
if (l != null)
{
l(null, args);
}
// 若不存在,执行默认事件
l = Handlers[""] as EventHandler<LoggerEventArgs>;
if (l != null)
{
l(null, args);
}
}
}
}
复制代码 . 针对事件数量多的情况(泛型版本) /// <summary> 复制代码
/// 日志类(第三版):适用于多事件情况的泛型版本。主要优势是降低了转型/转换的工作,但增加了一些用来映射事件的代码。
/// </summary>
public sealed class Logger
{
/// <summary>
/// 事件字典
/// </summary>
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)
{
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);
}
// 若不存在,则尝试执行默认事件
l = Handlers[""] as EventHandler<LoggerEventArgs>;
if (l != null)
{
l(null, args);
}
}
}
}
复制代码 至于选择哪种方式来实现,就要看具体的应用场景了;此外,大多数时候我们都会使用匿名委托来声明回调函数,或事件委托,所以会导致代码的运行时态有一些小波折,尤其在读别人的代码的时候,这样的情况很普遍,会不会有更好的办法来让这种回调和委托比较容易跟踪?这个还在思考中……

C#代码:用事件模式实现通知的更多相关文章

  1. OneAlert 入门(四)——事件分派和通知必达

    OneAlert 是国内首个 SaaS 模式的云告警平台,集成国内外主流监控/支撑系统,实现一个平台上集中处理所有 IT 事件,提升 IT 可靠性.有了 OneAlert,你可以更快更合理地为事件划分 ...

  2. 【转载】详细解读C#中的 .NET 弱事件模式

    你可能知道,事件处理是内存泄漏的一个常见来源,它由不再使用的对象存留产生,你也许认为它们应该已经被回收了,但不是,并有充分的理由. 在这个短文中(期望如此),我会在 .Net 框架的上下文事件处理中展 ...

  3. C#中的 .NET 弱事件模式

    引言 你可能知道,事件处理是内存泄漏的一个常见来源,它由不再使用的对象存留产生,你也许认为它们应该已经被回收了,但不是,并有充分的理由. 在这个短文中(期望如此),我会在 .Net 框架的上下文事件处 ...

  4. 在WPF中应用弱事件模式

    http://www.cnblogs.com/rickiedu/archive/2007/03/15/676021.html 在wpf中应用弱事件模式        感谢VS 的Intellisens ...

  5. WPF程序中的弱事件模式

    在C#中,得益于强大的GC机制,使得我们开发程序变得非常简单,很多时候我们只需要管使用,而并不需要关心什么时候释放资源.但是,GC有的时并不是按照我们所期望的方式工作. 例如,我想实现一个在窗口的标题 ...

  6. Java小知识----POI事件模式读取Excel 2007

    一.知识背景 1.读取excel的方法选择问题 java中读excel中的时间,我们通常用POI去解析,在使用new HSSFWorkbook(NEW FileInputStream(excelFil ...

  7. 从B站的代码泄露事件中,我们能学到些什么?

    先声明一下,本文不聊ISSUE中的七七八八,也不聊代码是否写的好,更不聊是不是跟蔡徐坤有关之类的吃瓜内容.仅站在技术人的角度,从这次的代码泄露事件,聊聊在代码的安全管理上,通常都需要做哪些事来预防此类 ...

  8. 190行代码实现mvvm模式

    前言 网上讲 vue 原理,mvvm 模式的实现,数据双向绑定的文章一搜一大堆,不管写的谁好谁坏,都是写的自己的理解,我也发一篇文章记录自己的理解,如果对看官有帮助,那也是我莫大的荣幸,不过看完之后, ...

  9. C# 标准事件模式

    .NET框架为事件定义了一个标准模式,它的目的是保持框架和用户代码之间的一致性. 标准事件的模式核心是SystemEventArgs——预定义的没有成员的框架类(不同于静态Empty属性) Event ...

随机推荐

  1. libbspatch.so

    http://www.zhihu.com/question/21154099 http://blog.csdn.net/hmg25/article/details/8100896 91助手和Googl ...

  2. 深入分析:Android中app之间的交互(二,使用ComponentName)

    在前一篇相关主题的博文中我们了解了如何使用Action来启动当前应用之外的Activity处理我们的业务逻辑,在本篇笔记中我在简单介绍一下使用ComponentName来与当前应用之外的应用进行交互. ...

  3. PHP版本区别

  4. Objective-C determine data network type of the iOS device

    Im on an application that receive data from server, the problem is when user connect to cellular dat ...

  5. codeforces Educational Codeforces Round 16-E(DP)

    题目链接:http://codeforces.com/contest/710/problem/E 题意:开始文本为空,可以选择话费时间x输入或删除一个字符,也可以选择复制并粘贴一串字符(即长度变为两倍 ...

  6. 2016年11月3日JS脚本简介数据类型: 1.整型:int 2.小数类型: float(单精度) double(双精度) decimal () 3.字符类型: chr 4.字符串类型:sting 5.日期时间:datetime 6.布尔型数据:bool 7.对象类型:object 8.二进制:binary 语言类型: 1.强类型语言:c++ c c# java 2.弱类型语

    数据类型: 1.整型:int 2.小数类型: float(单精度) double(双精度) decimal () 3.字符类型: chr 4.字符串类型:sting 5.日期时间:datetime 6 ...

  7. IOS的MVC

    1 翻牌游戏 1.1 问题 根据苹果MVC设计模式的思想原则实现一个简单的翻牌游戏,功能如下: 1)界面上随机摆放12张背面朝上的纸牌,界面效果如图-1所示: 图- 1 2)点击纸牌可以使纸牌翻页,翻 ...

  8. Maven打包可执行Jar包方式

    第一步:pom.xm中的build标签下加入maven插件配置,打包生成可执行jar包方式Maven中的打包方式更换为 <packaging>jar</packaging> b ...

  9. dedecms内容页调用缩略图 缩略图多种用法(借鉴)

    给大家分享一下文章内容页调用缩略图的方法. 这种问题是:文章有缩略图,但是文章里面没有,想把缩略图添加到文章里面. 1.文章内容页调用缩略图方法如下两种.第一种没有大小设置.原图显示.第二种.可以设大 ...

  10. 基于tcpdump实例讲解TCP/IP协议

    前言 虽然网络编程的socket大家很多都会操作,但是很多还是不熟悉socket编程中,底层TCP/IP协议的交互过程,本文会一个简单的客户端程序和服务端程序的交互过程,使用tcpdump抓包,实例讲 ...