.NET 4.0新功能介绍:In Process Side By Side

我们先来看一个在Outlook上运行.NET插件的一个情景。暂时机器上面安装的是CLR v1.1,Outlook上运行了一个Addin,在v1.1上编写和测试完毕,运行良好。之后,用户在机器上面安装v2.0。因为Outlook采取的方式是总是启动最新的.NET Framework(这也是有原因的,因为Outlook希望能够运行所有的版本的.NET Addin),Outlook自动会运行CLR v2.0(包括.NET Framework v2.0,v3.0, v3.5)。因为v2.0和v1.1之间并不是100%兼容,v1.1上编写的Addin在v2.0的CLR将有可能无法正确执行。也就是说,安装了一个新版本的.NET Framework可能会导致类似Outlook这样的支持插件的应用程序上的旧插件无法正确工作!

如果我们来看一下类似Outlook这样基于插件(Plugin或者Addin)的程序而言,选择CLR的版本大概有这么几种方式:

1. 总是最新:如上所述,总是选取最新的CLR加载存在兼容性问题。

2.总是坚持加载某个固定的版本:比如v1.1或者v2.0:如果总是固定某个版本,那么基于另外的CLR的版本的Addin将很难正常运行,要么是因为基于v1.1的CLR的Addin在v2.0 CLR上因为兼容性问题磕磕碰碰,要么是基于v2.0 CLR的Addin根本无法在v1.1 CLR上运行。

3. 加载Addin,第一个Addin所加载的CLR将是这个进程中的唯一CLR(注意目前CLR v1.Xv2.0不支持在一个进程中加载多个版本的CLR):先不提这种方法对于加载的CLR版本有一些随机性,不管是第一个Addin是v2.0还是v1.1,最终结果和上面几种方法并无出入。

可见,在目前的.NET/CLR的架构下,对于这种基于插件的应用程序运行多个基于不同CLR版本的插件并没有很好的解决方案。结果是,用户选择安装新版本的.NET可能会影响已有的程序。显然这在一定程度上将会影响到人们使用新版.NET的积极性,甚至导致拒绝升级到最新版本,显然,CLR开发小组是不愿意看到这种事情发生的。解决这个问题大致有两类思路:

1. 保持100%兼容,vN总是可以完美运行在vM上(M>N)

2. 承认100%兼容是不可能完成的任务,反之,允许多个不同版本的CLR共同执行

显然,方法一是完全不可行的,原因很简单,开发过应用程序平台的朋友们都知道,新版本的平台和旧版本的平台总是会由于各种原因不兼容。一些常见的原因有:

1. 旧的API被新的API所取代,旧API无法在新版本中使用。虽然常见的情况是新API和旧API并存,不过一旦并存了若干的版本之后,包袱总有被丢弃的一天。

2. 已有的API行为因为有若干缺陷,必须修改其行为。这种情况比较少见,通常的方法是加一个新的API,但是这种情况还是客观存在的。

3. 用户程序依赖于一些未定义行为,而这些未定义行为在新版本中有所改变(比如一个API的Bug,一个实现细节,或者CLR DLL的名字,等等)

4. 新的版本中有Bug,导致已有API行为改变

5. 使用某个固定的版本号

等等。因此,CLR采取的是第二个思路:支持多个不同版本的CLR互不干扰的共同执行,也就是Side By Side。注意,这里的Side By Side是一个很广义的词汇,它所指的是不同的CLR彼此之间互不干扰。这里的互不干扰也是有好几种层次的:

1. Out-Of-Process Side By Side:机器上可以安装不同版本的CLR,每个进程可以运行不同版本的CLR,互相之间互不干扰,共享机器范围的资源(如磁盘,注册表等)。目前v1.X、v2.0实现了这个功能。

2. In-Process Side By Side:同一个进程内可以运行多个CLR,每个CLR实例互不干扰,把对方看成本机代码。这里又分为几个层次:

a. 不同版本的CLR可以在同一个进程内加载,不允许同一个版本CLR加载多次

b. 允许加载同一个版本的CLR多次,彼此之间互不影响

可以看到,如果CLR可以支持在同一个进程中加载不同版本的CLR,也就是支持2.a,那么前面所提到的那个问题也就迎刃而解:v1.1的Addin运行在v1.1上,v2.0的Addin运行在v2.0上,顿时两个Addin便可以同时运行,互不干扰了!

幸运的是,CLR开发小组已经注意到了这个问题,并且在v4.0的CLR中实现了多个不同版本CLR的In-Process SxS,简称In-Proc SxS(也就是上面2.a所提到的内容)。下面本文将详细介绍v4.0中In-Proc SxS功能。

V4.0In-Proc SxS简介

在v4.0中CLR支持下列情况的In-Proc SxS:

1. v2.0v4.0共存

2. v1.1v4.0共存

而V1.1和V2.0则是不能够被同时加载到进程中。也就是说,进程中<4.0的CLR只能存在一个实例,这样做的原因非常简单:<4.0的CLR版本本身是不支持In-Proc SxS的,也就是说v1.1和v2.0一旦在同一个进程内加载是会出现各种各样的问题的。并且,我们不希望因为要支持SxS而去修改v1.1和v2.0,这样做的代价太大,同时也会把整个问题域变得更加复杂,因此最后决定不支持<4.0的CLR多于一个实例。当然了,>=4.0的CLR是可以多个并存的,也就是说V4.0,V5.0,v6.0,等等,都是可以和平共处在同一个进程内。原因很简单,>4.0的CLR是In-Proc SxS Aware的。

前面提到过,总是加载最新版本的CLR这种方式是存在问题的,因为新版本不可能完全兼容旧版本,因此,保持兼容性的最佳方式是不允许“加载最新”(Bind to latest)这种方式存在,换句话说,为v4写的程序缺省应该总是在v4上运行,而不应该自动被“提升”至V5上运行。

因为<4.0的CLR是不支持In-Proc SxS的,因此为了让这些CLR和新的V4和平共处,并且行为不变,必须满足下面几条:

1. 老程序的行为必须和原来保持一致,这包括已有程序的加载和已有的Hosting API

2. =v4.0的CLR,因为它们生活在两个不同的世界中

3. 已有的Hosting API只允许加载一个

可以看到,已有的HostingAPI因为没有设计成支持In-Proc SxS,在v4.0的时候会面临淘汰。而在v4.0的时候,v4.0的CLR(其实严格来说是Shim,也就是mscoree.dll)必须得有一套新的API。

CLR所做的修改

从v2.0到v4.0,从不支持In-Proc SxS到支持In-Proc SxS,CLR做出了不少的修改,这里面有不少的挑战。其中一个比较明显的修改是CLR的实现原来位于mscorwks.dll,现在被修改成了CLR.dll,同时JIT的实现原来是mscorjit,现在则是clrjit。原因非常简单,为了让已有的v1.1和v2.0的代码看不到V4的存在,避免v2.0的DLL把v4.0的CLR误认为是V2的。如果不做名字修改,已有的v2.0的代码很有可能仍然可以找到v4.0,因为内部的很多代码都是需要查找mscorwks.dll的。如果找不到这个DLL自然就找不到CLR了。

除此之外,CLR的代码也做出了不少的改变&#

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值