.Net AppDomain详解(一)
AppDomain是CLR实现代码隔离的基本机制。
AppDomain被创建在进程中,一个进程内可以有多个AppDomain。一个AppDomain只能属于一个进程。
当然这个说法很可能是和CLR的实现相关的。
Assembly是.Net程序的基本部署单元,它可以为CLR提供用于识别类型的元数据等等。
任何对象只能属于一个AppDomain。AppDomain用来隔离对象,不同AppDomain之间的对象必须通过Proxy(reference type)或者Clone(value type)通信。
值类型需要设置Serializable属性才能被Marshal/UnMarshal(Clone)。
AppDomain和程序集的源代码是什么关系呢?每个程序集的代码会分别装载到各个AppDomain中?
首先我们要把程序集分3类
1.mscorlib,这是每个.net程序都要引用到的程序集。
2.GAC,这个是强命名的公用程序集,可以被所有的.net程序引用。
3.Assembly not in GAC,这是普通的assembly,可以不是强命名,不放到GAC中。
static void Main()
{...}
Value | Expected Domains in Process | Each Domain Expected to Run ... | Code for MSCORLIB | Code for Assemblies in GAC | Code for Assemblies not in GAC |
---|---|---|---|---|---|
SingleDomain | One | N/A | Per-process | Per-domain | Per-domain |
MultiDomain | Many | Same Program | Per-process | Per-process | Per-process |
MultiDomainHost | Many | Different Programs | Per-process | Per-process | Per-domain |
1.SingleDomain,由于只启动一个AppDomain,那么code就被直接装载到了AppDomain中,访问静态变量更快捷。
C#中动态加载和卸载DLL
在C++中加载和卸载DLL是一件很容易的事,LoadLibrary和FreeLibrary让你能够轻易的在程序中加载DLL,然后在任何地方 卸载。在C#中我们也能使用Assembly.LoadFile实现动态加载DLL,但是当你试图卸载时,你会很惊讶的发现Assembly没有提供任何 卸载的方法。这是由于托管代码的自动垃圾回收机制会做这件事情,所以C#不提供释放资源的函数,一切由垃圾回收来做。
这引发了一个问题,用Assembly加载的DLL可能只在程序结束的时候才会被释放,这也意味着在程序运行期间无法更新被加载的DLL。而这个功能在某 些程序设计时是非常必要的,考虑你正在用反射机制写一个查看DLL中所有函数详细信息的程序,程序提供一个菜单让用户可以选择DLL文件,这时就需要让程 序能够卸载DLL,否则一旦用户重新得到新版本DLL时,必须要重新启动程序,重新选择加载DLL文件,这样的设计是用户无法忍受的。
C#也提供了实现动态卸载DLL的方法,通过AppDomain来实现。AppDomain是一个独立执行应用程序的环境,当AppDomain被卸载的 时候,在该环境中的所有资源也将被回收。关于AppDomain的详细资料参考MSDN。下面是使用AppDomain实现动态卸载DLL的代码,
using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Reflection; namespace UnloadDll { class Program { static void Main(string[] args) { string callingDomainName = AppDomain.CurrentDomain.FriendlyName;//Thread.GetDomain().FriendlyName; Console.WriteLine(callingDomainName); AppDomain ad = AppDomain.CreateDomain("DLL Unload test"); ProxyObject obj = (ProxyObject)ad.CreateInstanceFromAndUnwrap(@"UnloadDll.exe", "UnloadDll.ProxyObject"); obj.LoadAssembly(); obj.Invoke("TestDll.Class1", "Test", "It's a test"); AppDomain.Unload(ad); obj = null; Console.ReadLine(); } } class ProxyObject : MarshalByRefObject { Assembly assembly = null; public void LoadAssembly() { assembly = Assembly.LoadFile(@"TestDLL.dll"); } public bool Invoke(string fullClassName, string methodName, params Object[] args) { if(assembly == null) return false; Type tp = assembly.GetType(fullClassName); if (tp == null) return false; MethodInfo method = tp.GetMethod(methodName); if (method == null) return false; Object obj = Activator.CreateInstance(tp); method.Invoke(obj, args); return true; } } }
注意:
1. 要想让一个对象能够穿过AppDomain边界,必须要继承MarshalByRefObject类,否则无法被其他AppDomain使用。
2. 每个线程都有一个默认的AppDomain,可以通过Thread.GetDomain()来得到
更多:
C#如何测试代码运行时间
C# 访问操作注册表整理
C#中如何获取系统环境变量等
http://www.cnblogs.com/HopeGi/p/6422357.html
http://www.cnblogs.com/awpatp/archive/2009/11/24/1609570.html
转载于:https://www.cnblogs.com/tianma3798/p/7497272.html
.Net AppDomain详解(一)相关推荐
- .Net AppDomain详解(二)
AppDomain 类 表示应用程序域,它是一个应用程序在其中执行的独立环境. 此类不能被继承. 命名空间: System 程序集: mscorlib(位于 mscorlib.dll) 继承层次 ...
- App.Config详解
App.Config详解 应用程序配置文件是标准的 XML 文件,XML 标记和属性是区分大小写的.它是可以按需要更改的,开发人员可以使用配置文件来更改设置,而不必重编译应用程序. 配置文件的根节点是 ...
- 【转】__declspec用法详解
__declspec用法详解 __declspec用于指定所给定类型的实例的与Microsoft相关的存储方式.其它的有关存储方式的修饰符如static与extern等是C和 C++语言的ANSI规范 ...
- ASP.NET页面与IIS底层交互和工作原理详解(一)
第一回: 引言 我查阅过不少Asp.Net的书籍,发现大多数作者都是站在一个比较高的层次上讲解Asp.Net.他们耐心.细致地告诉你如何一步步拖放控件.设置控件属性.编写CodeBehind代码,以实 ...
- 8天掌握EF的Code First开发系列之3 管理数据库创建,填充种子数据以及LINQ操作详解...
本文出自8天掌握EF的Code First开发系列,经过自己的实践整理出来. 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LI ...
- (转)C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解
原文链接:https://www.cnblogs.com/landeanfen/p/5501487.html 阅读目录 一.void无返回值 二.IHttpActionResult 1.Json(T ...
- Nlog详解---非常详细
一.Nlog详解 1.概述 NLog是一个基于.NET平台编写的日志记录类库,我们可以使用NLog在应用程序中添加极为完善的跟踪调试代码.可以在任何一种.NET语言中输出带有上下文的(contextu ...
- [ASP.NET]ASP.NET中的Inherits、CodeFile、CodeBehind的区别详解及OWIN及IDENTITY
篇一 : ASP.NET中的Inherits.CodeFile.CodeBehind的区别详解 Inherits.CodeFile.CodeBehind 在 ASP.NET 中使用代码隐藏方法来设计W ...
- 详解c# Emit技术
我们常常有一个应用场景,由我们的C#代码,动态生成一个EXE,其应用场景可以非常多,比如软件授权,可以输入授权信息后,生成一个授权的DLL等,那如何实现这个功能呢,就要提到一个技术Emit. 1.Em ...
最新文章
- 全球人工智能战略与政策观察(2019)
- 模糊数学笔记:四、模糊矩阵与模糊关系
- 盲僧一键r闪用什么设置_美加狮R.A.T. PRO X3至尊版带你畅玩模拟飞行
- C++ —— C++引用
- jQuery-动画与特效
- android file isdirectory,android – 为什么我不能在Environment.DIRECTORY_PICTURES中创建一个目录?...
- Linux内核:VFIO Mediated Device(vfio-mdev)内核文档(翻译)
- 《编写可维护的JavaScript》——2.2 多行注释
- SQL中一种类似GUID值的函数实现
- mysql 5.1.71_MySQL升级从5.1.71到5.7.17
- sir节点matlab模型,SIR模型实现(matlab)
- psp记忆棒测试软件,PSP记忆棒有问题?修复软件MS-Format帮你解忧
- 想去美国?看完会成功率飙升的美国签证面试技巧
- xingtai - 时间
- RK1109_RK1126GMAC以太网配置问题
- python 二维列表获取其中元素_Python中二维列表如何获取子区域元素的组成
- Unity5 0 天空盒 CubeMap
- 2011年国外最受欢迎的15个购物网站
- 物联网专业可以报计算机岗位吗,现在物联网工程专业的就业岗位有哪些?小编介绍...
- Ubuntu16.04调试北阳(HOKUYO)UST-20LX激光雷达