接上文 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. 让元素div消失在视野中

    让元素div消失在视野中1.position:absolute/relative/fixed + 方位 top/bottom/left/right: -9999px2.display:none3.vi ...

  2. linux top-显示或管理执行中的程序

    推荐:更多linux 性能监测与优化 关注:linux命令大全 top命令可以实时动态地查看系统的整体运行情况,是一个综合了多方信息监测系统性能和运行信息的实用工具.通过top命令所提供的互动式界面, ...

  3. gnulpot

    gnulpot Table of Contents 1. Label position 2. coordinates 3. Symbols 4. key 4.1. key position 4.2. ...

  4. PAT 1137 Final Grading

    For a student taking the online course "Data Structures" on China University MOOC (http:// ...

  5. [bzoj1878][SDOI2009][HH的项链] (莫队算法)

    Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此, 他的项链变 ...

  6. 3.5.6 关系和boolean运算符

        Java包含丰富的关系运算符.要检测相等性,可以使用两个等号 == .例如, 3 == 7  的值为 false.       另外可以使用 != 检测不相等.例如,  3  ! = 7 的值 ...

  7. vs2017 添加引用时 未能完成操作。不支持此接口

    打开vs2017开发者命令提示符 切换至安装下的指定目录 执行下面的命令就可以了    需要注意的是一定要用vs2017的开发人员命令提示符  别用cmd gacutil -i Microsoft.V ...

  8. 51. spring boot属性文件之多环境配置【从零开始学Spring Boot】

    原本这个章节是要介绍<log4j多环境不同日志级别的控制的>但是没有这篇文章做基础的话,学习起来还是有点难度的,所以我们先一起了解下spring boot属性文件之多环境配置,当然文章中也 ...

  9. poj 2823单调队列模板题

    #include<stdio.h>//每次要吧生命值长的加入,吧生命用光的舍弃 #define N  1100000 int getmin[N],getmax[N],num[N],n,k, ...

  10. C语言编程规范试题(标准答案)

    C语言编程规范试题(标准答案) 一.单选题(每小题3分,共20小题60分) 1.1-1.5    B D A C B                1.6-1.10    C A D B C 1.11 ...