.NET跨AppDomain访问对象
什么是AppDomain?
我们都知道windows进程,它起到应用程序隔离的作用,带来的好处是,当某个进程发生错误的时候,不会影响其他的进程,系统也不会受到影响。但是,创建windows进程的代价是很大的。.net推出AppDomain的作用也是隔离,如果能确保应用程序都是安全代码(managed code),那么appdomain其实就可以起到进程的作用。每个appdomain里有自己的堆,负责自己内部对象的创建和销毁,对象一般不能夸appdomain访问。
当应用程序启动,CLR加载后,会创建一个appdomain(默认的,它知道进程结束才会unload),程序集会在此appdomain中加载,运行。
Appdomain,程序集,进程的关系如下图所示:
这里有个问题,即同样的assembly会在不同的appdomain中使用,会造成资源的浪费,所以出现了domain-neutral assemblies,也就是说,这些assemblies与appdomain无关,CLR负责管理,对象的创建,销毁都由CLR负责,当然,它们也只有等到CLR结束,也就是进程结束时才能unload。
跨AppDomain访问对象
CLR Via C#书中第22章的例子,很好的解释了如何跨appdomain对象访问。
它会建一个新的appdomain,在这里会创建(返回)3种类型的对象,1个是继承自MarshaByRefObject类型的对象,1个是标注了[Serializable]的类型的对象,另一个是普通类型对象,对应有3个#demo。
#demo1
在新的appdomain中动态创建继承自MarshaByRefObject类型的对象,然后在默认的appdomain中使用它的方法:
(1) 在新appdomain中create的对象,返回给原appdomain,实际上返回给原appdomain的是一个代理,也就是说mbrt变量指向的是一个proxy,而非新appdomain中的instance,所以IsTransparentProxy返回true。
(2) 在代理上执行方法,显然是在远程执行。
(3) 当新的appdomain卸载后,代理找不到原始对象,抛异常。
#demo2
在新的appdomain中动态创建标有[Serializable]的类型的对象,然后再默认的appdomain中使用
(1) 在新的appdomain创建的,返回原appdomain的,不会是代理,而是新appdomain中创建的对象的copy,在跨appdomain边界的时候序列化成字节流,回到原appdomain时,反序列化回来的,所以IsTransparentProxy返回false。
(2) 由于mbvt指向的对象不是代理对象,所以在本地(本appdomain)执行。
(3) 由于在本地执行,所以尽管新的appdomain被unload了,仍然可以继续执行。
#demo3
在新的appdomain中动态创建普通类型对象,既没有继承自MarshalByRefObject,也没有标注[Serializable],然后再默认的appdomain中使用,这个时候,由于新appdomain发现,既不能按Marshal by ref封送,就按Marshal by value封送,但是却不能序列化,所以只有跑序列化失败的异常了:
结论:跨appdomain对象访问有2种方式:by ref, by value,
(1) by ref要求对象继承自MarshalByRefObject,并且在目的appdomain中使用的是代理。
(2) by value要求对象标注[Serializable],即能被序列化,那么在目的appdomain中,使用的就是原对象的副本了。
.NET跨AppDomain访问对象的更多相关文章
- 解析.NET对象的跨应用程序域访问--AppDomain(上篇)
在目前的项目开发中,分布式开发已经逐渐成为主流.一个项目要是没有采用分布式架构,都不好意思跟别人说这是一个完整的项目.这句话虽然有些过激,但是随着人们对效率的要求在提高,以及产品需要提升用户体验.只有 ...
- 解析.NET对象的跨应用程序域访问(下篇)
转眼就到了元宵节,匆匆忙忙的脚步是我们在为生活奋斗的写照,新的一年,我们应该努力让自己有不一样的生活和追求.生命不息,奋斗不止.在上篇博文中主要介绍了.NET的AppDomain的相关信息,在本篇博文 ...
- 解析.NET对象的跨应用程序域访问(上篇)
在目前的项目开发中,分布式开发已经逐渐成为主流.一个项目要是没有采用分布式架构,都不好意思跟别人说这是一个完整的项目.这句话虽然有些过激,但是随着人们对效率的要求在提高,以及产品需要提升用户体验.只有 ...
- Chrome浏览器扩展开发系列之十五:跨域访问的XMLHttpRequest对象
XMLHttpRequest对象是W3C的标准API,用于访问服务器资源.XMLHttpRequest对象支持多种文本格式,如XML和JSON等.XMLHttpRequest对象可以通过HTTP和HT ...
- 解决Entity Framework查询匿名对象后的跨域访问的一种方式
在Entity Framework中,可以使用lambda表达式进行对数据的查询,而且可以将查询结果直接映射为对象或者对象列表,这极大的提高的开发速度,并且使数据层的数据更加方便处理和传递.但是很多时 ...
- Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置
Asp.Net SignalR 使用记录 工作上遇到一个推送消息的功能的实现.本着面向百度编程的思想.网上百度了一大堆.主要的实现方式是原生的WebSocket,和SignalR,再次写一个关于A ...
- 对象存储 COS 帮您轻松搞定跨域访问需求
背景 早期为了避免 CSRF(跨站请求伪造) 攻击,浏览器引入了 "同源策略" 机制.如果两个 URL 的协议,主机名(域名/IP),端口号一致,则视为这两个 URL " ...
- 阿里云对象存储OSS————跨域资源共享(CORS)(m3u8 无法加载m3u8:跨域访问被拒绝)
今天在做视频直播录像的时候,添加一个录制APP的.M3U8文件到OSS的一个test文件中存储,结果是访问不到了: 提示:无法加载m3u8:跨域访问被拒绝!!!!! 项目代码测试地址:https:// ...
- cookie 跨域访问的解决方案
Cookie 同域单点登录 最近在做一个单点登录的系统整合项目,之前我们使用控件实现单点登录(以后可以介绍一下).但现在为了满足客户需求,在不使用控件情况下实现单点登录,先来介绍一下单点登录. ...
随机推荐
- LeetCode() Super Ugly Number
用了优先队列,还是超时 class Solution { public: int nthSuperUglyNumber(int n, vector<int>& primes) { ...
- Python3 之 import 和 当前目录
环境: Python-3.4.3 Web.py-0.37 安装 web.py 的时候,提示 ImportError: No module named 'utils' 看看源码,setup.py,有这么 ...
- Perl/Nagios – Can’t locate utils.pm in @INC
While trying to use a Nagios plugin I got an error saying that “Can’t locate utils.pm in @INC”. Foll ...
- 自动运维:Ansible -ansible tower
文档主页:http://docs.ansible.com/参考文档:http://docs.ansible.com/ansible/参考文档:http://docs.ansible.com/ansib ...
- treeGrid树形数据表格的json数据格式说明
在使用easyUI 的treeGrid的时候,很多时候我们从数据库取出来的数据treeGrid却不能读取显示成一个树:如下 { menuCode: "a00", menuName: ...
- struts2中web.xml的配置
在web.xml</web-app>前添加的<filter></filter>和<filter-mapping></filter-mapping& ...
- 记录思想分享知识编辑器 Markdown 编辑阅读器
web使用:实现网页客户端实时自动解析Markdown为HTML内容小小的展示:Cmd Markdown 编辑阅读器使用必要性:怎样引导新手使用 Markdown? - 写作
- Sphinx的配置和使用
项目中用到了,昨天老大又给讲了讲,我感觉这玩意真是强大.想把一些功能以很小的代价做好,第三方的工具是必须要掌握的. 1. 我的开发环境在Windows上,下载了sphinx-2.2.6-release ...
- 黄聪:远程连接mysql数据库注意事项记录(远程连接慢skip-name-resolve)
远程连接慢 慢是一个很大的问题,网上的办法是在my.ini的“[mysqld]”下面加入一行“skip-name-resolve”,就像这样: 然后保存并重启mysql服务即可. 下面是其它网友的补充 ...
- 使用git新建分支以及管理分支
在进行分支相关的操作前, 我们需要保持主分支干净, 所谓的干净就是没有任何改变(所有更改都已经commit 并 push),那么你可以在任何时候从你的主分支创建一个新分支. 为了方便代码管理,我们应该 ...