.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()来得到
更多:
http://www.cnblogs.com/HopeGi/p/6422357.html
http://www.cnblogs.com/awpatp/archive/2009/11/24/1609570.html
.Net AppDomain详解(一)的更多相关文章
- .Net AppDomain详解(二)
AppDomain 类 表示应用程序域,它是一个应用程序在其中执行的独立环境. 此类不能被继承. 命名空间: System程序集: mscorlib(位于 mscorlib.dll) 继承层次结 ...
- C# AppDomain 详解
AppDomain 详解 AppDomain是CLR的运行单元,它可以加载Assembly.创建对象以及执行程序. AppDomain是CLR实现代码隔离的基本机制.每一个AppDomain可以单独运 ...
- AppDomain 详解(转)
AppDomain是CLR的运行单元,它可以加载Assembly.创建对象以及执行程序. AppDomain是CLR实现代码隔离的基本机制. 每一个AppDomain可以单独运行.停止:每个AppDo ...
- C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解
前言:已经有一个月没写点什么了,感觉心里空落落的.今天再来篇干货,想要学习Webapi的园友们速速动起来,跟着博主一起来学习吧.之前分享过一篇 C#进阶系列——WebApi接口传参不再困惑:传参详解 ...
- App.Config详解及读写操作
App.Config详解及读写操作 App.Config详解 应用程序配置文件是标准的 XML 文件,XML 标记和属性是区分大小写的.它是可以按需要更改的,开发人员可以使用配置文件来更改设置,而 ...
- 8天掌握EF的Code First开发系列之3 管理数据库创建,填充种子数据以及LINQ操作详解
本文出自8天掌握EF的Code First开发系列,经过自己的实践整理出来. 本篇目录 管理数据库创建 管理数据库连接 管理数据库初始化 填充种子数据 LINQ to Entities详解 什么是LI ...
- log4net详解(转载)
1.概述 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.本文主要是介绍如何在Visual S ...
- App.Config详解
App.Config详解 应用程序配置文件是标准的 XML 文件,XML 标记和属性是区分大小写的.它是可以按需要更改的,开发人员可以使用配置文件来更改设置,而不必重编译应用程序.配置文件的根节点是c ...
- c# App.Config详解
c# App.Config详解 应用程序配置文件是标准的 XML 文件,XML 标记和属性是区分大小写的.它是可以按需要更改的,开发人员可以使用配置文件来更改设置,而不必重编译应用程序. 配置文件的根 ...
随机推荐
- linux通过wget直接下载jdk
下载语句: tar包下载 wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-se ...
- 【Java】 int与char类型间的相互转化
在[Java] 剑指offer(16) 打印1到最大的n位数中遇到了int类型与char类型之间的转换,这里总结一下. (1)int类型转char类型,将数字加一个‘0’,并强制类型转换为char即可 ...
- chrome如何在选项卡打开网页
1.鼠标中间点击,会打开新选项卡 2.按住ctrl,然后鼠标点击,也是可以的 3.
- Java string.valueof的用法以及与parseint的区别
一.由基本数据型态转换成String String 类别中已经提供了将基本数据型态转换成 String 的 static 方法 ,也就是 String.valueOf() 这个参数多载的方法 有以下几 ...
- 001.Git简介与安装
一 git介绍 1.1 概述 Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放 ...
- jstat命令总结
jvm统计信息监控工具 一. jstat是什么 jstat是JDK自带的一个轻量级小工具.全称"Java Virtual Machine statistics monitoring tool ...
- Ubuntu 18.04 更新源
[原因] 使用国外的源,在更新软件的时候会很慢,换成国内的源会快很多. [命令] 1.备份源文件 sudo cp /etc/apt/sources.list /etc/apt/sources.list ...
- BZOJ.1031.[JSOI2007]字符加密(后缀数组)
题目链接 环可以拆成链:对字符串排序能想到后缀数组. 完了.输出时忽略长度不足n的串,输出s[sa[i]+n-1],即排名为i的字符串的末尾. //4140kb 744ms #include < ...
- POJ.2454.Jersey Politics(随机化算法)
题目链接 \(Description\) 将长为\(3n\)的序列划分成\(3\)个子序列,要求至少有两个子序列的和都\(\geq 500*n\),输出任一方案.保证有解. \(Solution\) ...
- [POI2014]Rally
OJ题号:BZOJ3832.洛谷3573 思路: 建立超级源汇$S$和$T$,DP求出分别以$S$和$T$为源点的最长路$diss$和$dist$. 对于每条边$i$,设定一个权值$w_i=diss_ ...