AppDomain (转)
AppDomain是CLR实现代码隔离的基本机制。
一个AppDomain的运行失败不会影响到其他的AppDomain。
AppDomain被创建在进程中,一个进程内可以有多个AppDomain。一个AppDomain只能属于一个进程。
其实两者本来没什么好对比的。AppDomain是个静态概念,只是限定了对象的边界;线程是个动态概念,它可以运行在不同的
AppDomain。
一个AppDomain内可以创建多个线程,但是不能限定这些线程只能在本AppDomain内执行代码。
一个soft thread只属于一个AppDomain,穿越AppDomain的是hard thread。当hard thread访问到某个AppDomain时,一个
当然这个说法很可能是和CLR的实现相关的。
Assembly是.Net程序的基本部署单元,它可以为CLR提供用于识别类型的元数据等等。Assembly不能单独执行,它必须被加载到
一个Assembly可以被多个AppDomain加载,一个AppDomain可以加载多个Assembly。
任何对象只能属于一个AppDomain。AppDomain用来隔离对象,不同AppDomain之间的对象必须通过Proxy(reference 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()来得到
AppDomain (转)的更多相关文章
- AppDomain对于静态对象的独享引用
AppDomain可以理解为一个独立的沙箱,当有独立的第静态对象在appDomain中被访问时,会在appDomain中产生独立的内存对象.比如appDomain1 appDomain2同时对 静态对 ...
- AppDomain 详解(转)
AppDomain是CLR的运行单元,它可以加载Assembly.创建对象以及执行程序. AppDomain是CLR实现代码隔离的基本机制. 每一个AppDomain可以单独运行.停止:每个AppDo ...
- 同一AppDomain内的SharpGL的FrameBuffer会相互影响?
同一AppDomain内的SharpGL的FrameBuffer会相互影响? 今天做一个试验时,偶然发现了这样一个问题. 以SharpGL的示例项目SimpleDrawingSample为例. 给Fo ...
- C#中AppDomain.CurrentDomain.BaseDirectory及各种路径获取方法
// 获取程序的基目录.System.AppDomain.CurrentDomain.BaseDirectory // 获取模块的完整路径,包含文件名System.Diagnostics.Proces ...
- 【C#进阶系列】22 CLR寄宿和AppDomain
关于寄宿和AppDomain 微软开发CLR时,将它实现成包含在一个DLL中的COM服务器. 任何Windows应用程序都能寄宿(容纳)CLR.(简单来讲,就是CLR在一个DLL中,通过引用这个DLL ...
- Failed to create AppDomain 'xxx'. Exception has been Failed to create AppDomain
一服务器上的数据库全部被置于紧急模式(EMERGENCY),在错误日志里面能看到大量下面的错误 Failed to create AppDomain "YourSQLDba.dbo[runt ...
- .NET跨AppDomain访问对象
什么是AppDomain? 我们都知道windows进程,它起到应用程序隔离的作用,带来的好处是,当某个进程发生错误的时候,不会影响其他的进程,系统也不会受到影响.但是,创建windows进程的代价是 ...
- 卸载AppDomain动态调用DLL异步线程执行失败
应用场景 动态调用DLL中的类,执行类的方法实现业务插件功能 使用Assembly 来实现 但是会出现逻辑线程数异常的问题 使用AppDomain 实现动态调用,并卸载. 发现问题某个插件中开启异步线 ...
- 跨应用程序域(AppDomain)的单例(Singleton)实现
转载自: 跨应用程序域(AppDomain)的单例(Singleton)实现 - CorePlex代码库 - CorePlex官方网站,Visual Studio插件,代码大全,代码仓库,代码整理,分 ...
- C#学习笔记----AppDomain应用程序域
使用.Net建立的可执行程序*.exe,并没有直接承载到进程当中,而是承载到应用程序域(AppDomain)当中.应用程序域是.Net引入的一个新概念,它比进程所占用的资源要少,可以被看做是一个轻量级 ...
随机推荐
- 2,Executor线程池
一,Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java.util.co ...
- luogu【P1024 一元三次方程求解】题解
题目描述 有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程.给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差 ...
- Activiti的流程实例及挂起激活(七)
1.1什么是流程实例 参与者(可以是用户也可以是程序)按照流程定义内容发起一个流程,这就是一个流程实例.是动态的.流程定义和流程实例的图解: 1.2启动流程实例 流程定义部署在 activiti 后, ...
- [springboot jpa] [bug] Could not open JPA EntityManager for transaction
前言 最近,测试环境遇到了一个问题.经过一番百度加谷歌,终于解决了这个问题.写下这篇博客是为了记录下解决过程,以便以后查看.也希望可以帮助更多的人. 环境 java版本:8 框架:spring clo ...
- 微信小程序之登录用户不是该小程序的开发者
当uniapp项目转为小程序项目的时候,预览会显示“您不是登录用户...”,所以没有办法发布,这个时候打开“project.config.json”设置一下appid,与你公众号appid一致就可以
- Vue实现音乐播放器(四):页面入口+header组件的编写
首先下载三个包 babel-runtime对es语法进行转义 fastclick解决移动端点击300毫秒延迟的问题 babel-polyfill对es6 api进行转义 下载了包之后要在main.js ...
- 记一次odoo创建新的模块时,但是在odoo web界面找不到应用的案例
原因就是在odoo.conf配置文件中没有说明 模块查找的路径
- NacosValue 注解
NacosValue 定义在 nacos-api 工程中:com.alibaba.nacos.api.config.annotation.NacosValue 注解解析在 nacos-spring-p ...
- XML读写工具类
摘要:①读取XML文件,生成pojo对象:②将对象信息保存到xml中. 步骤: ①新建一个普通的java类BasePage: package com.test.selenium.pages; impo ...
- Week2 - 669. Trim a Binary Search Tree & 617. Merge Two Binary Trees
Week2 - 669. Trim a Binary Search Tree & 617. Merge Two Binary Trees 669.Trim a Binary Search Tr ...