接上文 MVVMLight消息通知实现机制详解(一)

  1. 该工具的内部主要逻辑是以字典模式进行储存持有订阅对象设置的传入参数Type类型、Key值、Action、Target(订阅对象本身)
  2. 在发生订阅事件和触发订阅事件时都会调用通过查询上述字典进行匹配,找到Key值相同&&Type类型相同的值,执行target的action并传入参数
  3. 扩展1:可发生没有key值的订阅事件,只要传参类型相同就可以
  4. 扩展2:可发生静态类的订阅事件,其内部有判断是否为static,static时target可为空

  找到源码看到,订阅事件部分代码:

  public virtual void Register<TMessage>( object recipient,object token,bool receiveDerivedMessagesToo,Action<TMessage> action,bool keepTargetAlive = false)
{
lock (_registerLock)
{
var messageType = typeof(TMessage); Dictionary<Type, List<WeakActionAndToken>> recipients; if (receiveDerivedMessagesToo)
{
if (_recipientsOfSubclassesAction == null)
{
_recipientsOfSubclassesAction = new Dictionary<Type, List<WeakActionAndToken>>();
} recipients = _recipientsOfSubclassesAction;
}
else
{
if (_recipientsStrictAction == null)
{
_recipientsStrictAction = new Dictionary<Type, List<WeakActionAndToken>>();
} recipients = _recipientsStrictAction;
} lock (recipients)
{
List<WeakActionAndToken> list; if (!recipients.ContainsKey(messageType))
{
list = new List<WeakActionAndToken>();
recipients.Add(messageType, list);
}
else
{
list = recipients[messageType];
} var weakAction = new WeakAction<TMessage>(recipient, action, keepTargetAlive); var item = new WeakActionAndToken
{
Action = weakAction,
Token = token
}; list.Add(item);
}
} RequestCleanup();
}

  以上是源码上订阅事件代码,其具体逻辑如下:

  1. 以Dictionary<Type, List<WeakActionAndToken>> 类型持有数据,对每一个订阅事件都是先在Dictionary的Key上查找是否存在该传参类型,不存在就添加该类型(Add(type,new List<WeakActionAndToken>)),存在就添加到该类型对应的Value列表中

  2. 在其Value值上是List<WeakActionAndToken>类型,WeakActionAndToken包含本次订阅事件的Action和Key值

  

  源码Send部分代码:

 private void SendToTargetOrType<TMessage>(TMessage message, Type messageTargetType, object token)
{
var messageType = typeof(TMessage); if (_recipientsOfSubclassesAction != null)
{
// Clone to protect from people registering in a "receive message" method
// Correction Messaging BL0008.002
var listClone =
_recipientsOfSubclassesAction.Keys.Take(_recipientsOfSubclassesAction.Count()).ToList(); foreach (var type in listClone)
{
List<WeakActionAndToken> list = null; if (messageType == type
|| messageType.IsSubclassOf(type)
|| type.IsAssignableFrom(messageType))
{
lock (_recipientsOfSubclassesAction)
{
list = _recipientsOfSubclassesAction[type].Take(_recipientsOfSubclassesAction[type].Count()).ToList();
}
} SendToList(message, list, messageTargetType, token);
}
} if (_recipientsStrictAction != null)
{
List<WeakActionAndToken> list = null; lock (_recipientsStrictAction)
{
if (_recipientsStrictAction.ContainsKey(messageType))
{
list = _recipientsStrictAction[messageType]
.Take(_recipientsStrictAction[messageType].Count())
.ToList();
}
} if (list != null)
{
SendToList(message, list, messageTargetType, token);
}
} RequestCleanup();
}

  以上是源码上发送事件消息代码,其具体逻辑如下:

  • 根据传参Type值在Dictionary<Type, List<WeakActionAndToken>>上查找对应List<WeakActionAndToken>列表
  • 然后对该列表内WeakActionAndToken进行匹配,对应Key值是否相同
  • 找到Key值相同的WeakActionAndToken执行其Action

  备注:在Send()部分应该加异步发送消息,个人自测频率太快的调用会造成卡顿延迟(类似心跳包这种就有点费劲)

  源码:MVVMLight的消息发送工具源码,可单独使用

MVVMLight消息通知实现机制详解(二)的更多相关文章

  1. MVVMLight消息通知实现机制详解(一)

    最近对委托.事件的订阅使用的太多,订阅与被订阅之间的绑定约束非常...麻烦,所以翻了下MVVMLight源码找出这段可以拿出来用的部分,详情见下: 一.开发中遇到的问题: 场景1:ClassA中存在事 ...

  2. Android的事件处理机制详解(二)-----基于监听的事件处理机制

    基于监听的事件处理机制 前言: 我们开发的app更多的时候是需要与用户的交互----即对用户的操作进行响应 这就涉及到了android的事件处理机制; android给我们提供了两套功能强大的处理机制 ...

  3. 二,PHP缓存机制详解

    一,PHP缓存机制详解 我们可以使用PHP自带的缓存机制来完成页面静态化,但是仅靠PHP自身的缓存机制并不能完美的解决页面静态化,往往需要和其他静态化技术(通常是伪静态技术)结合使用. output ...

  4. iOS的消息转发机制详解

    iOS开发过程中,有一类的错误会经常遇到,就是找不到所调用的方法,当然这类问题比较好解决,给当前对象或其父类对象添加该方法即可,使得编译器在编译时能正确找到该方法:或者,还有另外的方法,由于Objec ...

  5. nginx平台初识(二) 浏览器 HTTP 协议缓存机制详解

    1.缓存的分类 缓存分为服务端侧(server side,比如 Nginx.Apache)和客户端侧(client side,比如 web browser). 服务端缓存又分为 代理服务器缓存 和 反 ...

  6. “全栈2019”Java多线程第三十二章:显式锁Lock等待唤醒机制详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  7. JVM类加载机制详解(二)类加载器与双亲委派模型

    在上一篇JVM类加载机制详解(一)JVM类加载过程中说到,类加载机制的第一个阶段加载做的工作有: 1.通过一个类的全限定名(包名与类名)来获取定义此类的二进制字节流(Class文件).而获取的方式,可 ...

  8. [转]JavaScript异步机制详解

    原文: https://www.jianshu.com/p/4ea4ee713ead --------------------------------------------------------- ...

  9. ssion机制详解

    ssion机制详解   ref:http://justsee.iteye.com/blog/1570652 虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚sess ...

随机推荐

  1. 实战:tcp链接rst场景tcpdump分析

    RST为重置报文段,它会导致TCP连接的快速拆迁,且不需要ack进行确认. 1.针对不存在的端口的连请求 客户端: #include <unistd.h> #include <sys ...

  2. 小程序button默认样式透彻理解

    微信小程序有一个默认样式,特别是有一个外边框,虽然看起来不别扭,但是自己每次设置border:0:都不生效,写成内联的样式也不生效,后来才知道里面的边框是伪元素的边框,这里的伪元素可以理解为用css动 ...

  3. 洛谷——P1273 有线电视网

    P1273 有线电视网 题目大意: 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树 ...

  4. Loj #6000.「 网络流 24 题 」搭配飞行员

    解题思路 考虑如何建模. 既然是网络流,那么肯定要有源点和汇点.而这个题目并没有什么明显的源点和汇点. 想一想,如果一个飞机能够起飞的话,那么必定有一对可以配对的正副驾驶员.也就是说一条曾广路能够上必 ...

  5. UVA - 442 Matrix Chain Multiplication(栈模拟水题+专治自闭)

    题目: 给出一串表示矩阵相乘的字符串,问这字符串中的矩阵相乘中所有元素相乘的次数. 思路: 遍历字符串遇到字母将其表示的矩阵压入栈中,遇到‘)’就将栈中的两个矩阵弹出来,然后计算这两个矩阵的元素相乘的 ...

  6. Scrapy用Cookie实现模拟登录

    模拟登录是爬取某些站点内容的一个关键,有些网站(特别是论坛类),不登录的话,一个数据也拿不到. 模拟登录有这样几个关键: 弄清楚登录的url一些网站打开出现登录的页面,地址栏大多数不是登录提交表单的u ...

  7. ubuntu 安装codeblocks13.12

    通过添加PPA的方法安装: sudo add-apt-repository ppa:pasgui/ppa sudo apt-get update sudo apt-get install codebl ...

  8. scrapy 按顺序抓取text内容

    需求:获得如下li.clearfix 下的所有text,并且按顺序输出 1. x.css('div.reply-doc h4 a::text').extract(); 2.  x.css('div.r ...

  9. Python基础函数

    join()函数的用法 join()函数连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符)连接生成一个新的字符串 语法:'sep'.join(seq) 参数说明sep:分隔符.可以为空 ...

  10. Linux学习总结(19)——Linux中文本编辑器vim特殊使用方法

    1. vim比对功能 在linux的环境下 用于观察两个文件的一致性的时候我们一般用diff这个命令来比对,但是这个命令不能你特别详细的比对出 具体的位置或者行对比.这里就用到了vim的对比功能 vi ...