MVVMLight消息通知实现机制详解(二)
- 该工具的内部主要逻辑是以字典模式进行储存持有订阅对象设置的传入参数Type类型、Key值、Action、Target(订阅对象本身)
- 在发生订阅事件和触发订阅事件时都会调用通过查询上述字典进行匹配,找到Key值相同&&Type类型相同的值,执行target的action并传入参数
- 扩展1:可发生没有key值的订阅事件,只要传参类型相同就可以
- 扩展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();
}
以上是源码上订阅事件代码,其具体逻辑如下:
以Dictionary<Type, List<WeakActionAndToken>> 类型持有数据,对每一个订阅事件都是先在Dictionary的Key上查找是否存在该传参类型,不存在就添加该类型(Add(type,new List<WeakActionAndToken>)),存在就添加到该类型对应的Value列表中
- 在其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消息通知实现机制详解(一)
最近对委托.事件的订阅使用的太多,订阅与被订阅之间的绑定约束非常...麻烦,所以翻了下MVVMLight源码找出这段可以拿出来用的部分,详情见下: 一.开发中遇到的问题: 场景1:ClassA中存在事 ...
- Android的事件处理机制详解(二)-----基于监听的事件处理机制
基于监听的事件处理机制 前言: 我们开发的app更多的时候是需要与用户的交互----即对用户的操作进行响应 这就涉及到了android的事件处理机制; android给我们提供了两套功能强大的处理机制 ...
- 二,PHP缓存机制详解
一,PHP缓存机制详解 我们可以使用PHP自带的缓存机制来完成页面静态化,但是仅靠PHP自身的缓存机制并不能完美的解决页面静态化,往往需要和其他静态化技术(通常是伪静态技术)结合使用. output ...
- iOS的消息转发机制详解
iOS开发过程中,有一类的错误会经常遇到,就是找不到所调用的方法,当然这类问题比较好解决,给当前对象或其父类对象添加该方法即可,使得编译器在编译时能正确找到该方法:或者,还有另外的方法,由于Objec ...
- nginx平台初识(二) 浏览器 HTTP 协议缓存机制详解
1.缓存的分类 缓存分为服务端侧(server side,比如 Nginx.Apache)和客户端侧(client side,比如 web browser). 服务端缓存又分为 代理服务器缓存 和 反 ...
- “全栈2019”Java多线程第三十二章:显式锁Lock等待唤醒机制详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- JVM类加载机制详解(二)类加载器与双亲委派模型
在上一篇JVM类加载机制详解(一)JVM类加载过程中说到,类加载机制的第一个阶段加载做的工作有: 1.通过一个类的全限定名(包名与类名)来获取定义此类的二进制字节流(Class文件).而获取的方式,可 ...
- [转]JavaScript异步机制详解
原文: https://www.jianshu.com/p/4ea4ee713ead --------------------------------------------------------- ...
- ssion机制详解
ssion机制详解 ref:http://justsee.iteye.com/blog/1570652 虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚sess ...
随机推荐
- 题解 洛谷P1501/BZOJ2631【[国家集训队]Tree II】
Link-Cut-Tree 的懒标记下传正确食用方法. 我们来逐步分析每一个操作. 1:+ u v c:将u到v的路径上的点的权值都加上自然数c; 解决方法: 很显然,我们可以 split(u,v) ...
- Missing message for key "xxx" in bundle "(default bundle)" for locale zh_CN
参考文章http://programmerslounge.blogspot.com/2013/03/error-missing-message-for-key.html 错误的struts-confi ...
- python学习,使用requests库来模拟登录github,post请求。
这次我们要模拟登录的页面是 https://github.com/login 首先我们先尝试着登陆一遍分析一下请求, 打开开发者工具下的network选项, 可以很清楚的看到这个会话session,而 ...
- Python网络编程—socket(二)
http://www.cnblogs.com/phennry/p/5645369.html 接着上篇博客我们继续介绍socket网络编程,今天主要介绍的内容:IO多路复用.多线程.补充知识点. 一.I ...
- angular中多个promise的合并处理
all()方法 这个all()方法,可以把多个primise的数组合并成一个.当所有的promise执行成功后,会执行后面的回调.回调中的参数,是每个promise执行的结果.当批量的执行某些方法时, ...
- 使用HTML5 Canvas API
一.检测浏览器支持情况 HTML5 Canvas的确是一个好东西,但是并不是所有浏览器都支持HTML5 Canvas的,这就要求我们在使用HTML5 Canvas前要检查浏览器是否支持这玩意儿. 在创 ...
- WordCountPro,完结撒花
WordCountPro,完结撒花 软测第四周作业 一.概述 该项目github地址如下: https://github.com/YuQiao0303/WordCountPro 该项目需求如下: ht ...
- 55. spring boot 服务配置和部署【从零开始学Spring Boot】
Spring Boot 其默认是集成web容器的,启动方式由像普通Java程序一样,main函数入口启动.其内置Tomcat容器或Jetty容器,具体由配置来决定(默认Tomcat).当然你也可以将项 ...
- HDU1507 Uncle Tom's Inherited Land*
题目是跟 zoj1516是一样的,但多了匹配后的输出 详解zoj1516可见http://www.cnblogs.com/CSU3901130321/p/4228057.html #include & ...
- 转载 - Python里面关于 模块 和 包 和 __init__.py 的一些事
出处:http://www.cnblogs.com/tqsummer/archive/2011/01/24/1943273.html python中的Module是比较重要的概念.常见的情况是,事先写 ...