CLR Via C# 3rd 阅读摘要 -- Chapter 22 – CLR Hosting and AppDomains

CLR Hosting

  1. Assembly和Module的关系:Assembly至少有一个Module(通常是一个),Module没有装箱单(Manifest)元数据,VS IDE不能直接生成Module以及多个Module的Assembly,但是csc编译器可以通过/t[arget]: module输出Module,缺省扩展名是.netmodule,编译器可以通过/addmodule附加到目标上。参考:CLR Via C# 3rd 阅读摘要 -- Chapter 2 - Building, Packaging, Deploying, and Administering Applications and Types
  2. CLR被设计成COM服务器组件包含在一个DLL(MSCorWrks.dll(1.0, 1.1, 2.0)/Clr.dll(4.0))中;
  3. MetaHost.h头文件中定义了CLR COM的GUIDs以及非托管的ICLRMetaHost接口;
  4. 任何Windows应用程序都可以托管CLR,但是你不能通过调用CoCreateInstance创建CLR COM Server的实例;
  5. 你可以通过调用MetaHost.h中的CLRCreateInstance(实现在MSCorEE.dll中)来创建CLR COM Server;
  6. .NET Framework 3.0, 3.5装载的是2.0的CLR;
  7. CLRCreateInstance返回一个ICLRMetaHost的接口,托管应用程序可以调用该接口的GetRuntime函数,指定你希望创建的CLR版本;
  8. 任何应用都可以托管CLR的好处:
    • 多语言编程,编程语言无关;
    • 代码可以使用JIT编译来提高速度;
    • 代码可以使用垃圾收集器避免内存泄露和破坏;
    • 代码可以运行在安全沙箱中;
    • 不同担心开发环境,可以使用现有的技术:语言,编译器,编辑器,调试器,分析器,等等。
  9. 如何定制CLR?书籍:《Customizing the Microsoft .NET Framework Common Language Runtime》;
  10. 在.NET 4.0框架开始支持在一个Windows进程中同时加载2.0和4.0的CLR。

AppDomains

  1. AppDomain的目的就是为了隔离;
  2. AppDomain的特性:
    • 一个AppDomain中创建的对象不能直接被其他的AppDomain访问,要跨AppDomain访问对象,必须采用marshal-by-reference或者marshal-by-value语义;
    • AppDomains可以卸载;
    • AppDomains可以有独立的安全性;
    • AppDomains可以分别配置。
  3. CreateProcess Win32函数非常慢,Windows请求大量的内存来虚拟化进程地址空间;
  4. Windows托管AppDomains的进程模型:
  5. 一些程序集希望被多个AppDomains使用,比如MSCorLib.dll,以Domain-Neutral方式加载的程序集不能被卸载,除非CLR卸载;
  6. 怎样跨AppDomain边界访问对象?
    • 通过使用Marshal-by-Reference跨AppDomain通信。
      • 继承自MarshalByRefObject的类型应该避免定义任何静态成员;
      • 租约管理:当一个代理对象创建后,CLR保持该对象存活5分钟。
    • 通过使用Marshal-by-Value跨AppDomain通信。
      • MarshalByValType没有继承自MarshalByRefObject,所以CLR不能定义一个代理类型直接创建它的实例;
      • 当装载程序集时,CLR使用目标AppDomain的策略和配置。
    • 通过使用Non-Marshalable类型跨AppDomain通信。
      • 没有继承自MarshalByRefObject,虽然不能创建代理对象,但是如果标记有[Serializable],CLR可以序列化对象到一个字节数组,通过该字节数组来跨AppDomain边界通信;
      • System.String就是没有继承自MarshalByRefObject,但是有[Serializable]属性标记。
  7. 因为一个Windows进程中可以装载多个AppDomains,一个线程可以在一个AppDomain中执行代码然后再到另外一个AppDomain中执行;
  8. 当一个AppDomain创建时,可以设定一个友好名称。

AppDomain Unloading

  1. AppDomain.Unload静态方法可以卸载一个AppDomain;
  2. CLR如何卸载AppDomain:
    • CLR挂起执行托管代码进程中的所有线程;
    • CLR检查所有的线程栈看当前卸载的AppDomain中哪些线程正在执行代码或者有可能返回到代码中的某些点。CLR强制这些线程在他们的线程栈上抛出ThreadAbortException。CLR在这些情形下并不会立即终止执行代码:catch/finally块、类构造器、CER、非托管代码中;
    • 当上一步中发现的所有线程离开了AppDomain,CLR巡视堆并在每一个引用到卸载的AppDomain创建的真实对象的代理对象设置标记。如果有代码现在调用这些失效的代理对象上的方法,会抛出AppDomainUnloadedException异常;
    • CLR强制垃圾收集器工作;
    • CLR唤醒所有剩余的线程继续运行。
  3. 如果在卸载AppDomain的过程中调用AppDomain.Unload方法时,CLR会创建另外一个线程尝试卸载AppDomain。之前的卸载线程会被强制抛出ThreadAbortException。

AppDomain Monitoring

  1. AppDomain监视会招致额外的开销,必须显式的设置AppDomain.MonitoringEnabled静态属性来打开监视;
  2. MonitoringSurvivedProcessMemorySize、MonitoringTotalAllocatedMemorySize、MonitoringSurvivedMemorySize、MonitoringTotalProcessorTime;

AppDomain First-Chance Exception Notifications

  1. AppDomain.FirstChanceException事件;
  2. CLR如何处理一个异常:
    • 当异常第一次抛出时,CLR调用注册的FirstChanceException事件的回调方法;
    • 然后,CLR查找同一个AppDomain中的栈上的catch块。如果catch块处理了异常,正常继续。;
    • 否则CLR沿着Appdomain的栈再次抛出同样的异常(在序列化/反序列化之后)。这里抛出的是一个新异常,所以CLR调用FirstChanceException事件的回调方法;
    • 继续直至到达线程栈的顶端。到这里,如果异常没有被任何代码处理,CLR终止整个进程。

How Hosts Use AppDomains

  1. 可执行的应用程序:
    • 控制台程序、NT服务程序、Windows窗体程序、WPF程序,可以自我宿主的应用程序;
    • 调用System.Environment.Exit方法,首先会调用托管堆上的所有对象的Finalize方法,然后调用Win32的ExitFunction方法。
  2. SilverLight RIA应用程序:
    • SilverLight CLR(CoreClr.dll),每一个页面上的SilverLight控件运行在各自的AppDomain中。
  3. ASP.NET WebForm和XML Web服务程序:
    • 如果客户端请求一个不同的Web应用程序,ASP.NET告诉CLR创建一个新的AppDomain。这个新的AppDomain通常创建在同一个工作者进程中;
    • Shadow Copying:当一个磁盘上的Web站点的文件改变后,ASP.NET会检测到,接着卸载老的版本(当最后一个工作中的请求完成后),然后创建一个新的AppDomain,然后装载新的版本。
  4. Microsoft Sql Server:
    • Sql Server允许使用托管代码来开发存储过程。这意味着可以使用强类型,并且可以经过JIT编译后执行来取代解释执行。
  5. 你自己假想的情形。

Advanced Host Control

  1. 使用托管代码管理CLR,System.AppDomainManager;
  2. 宿主应用程序如何理解线程返回?

本章小结

  本章主要讨论了两个概念:Hosting和AppDomains。Hosting允许任何应用程序利用CLR的特性;AppDomain是进程中的一个逻辑区域,一个进程可以加载多个AppDomain,一个AppDomain中可以加载多个Assembly,AppDomain还可以被卸载。AppDomain可以为插件应用程序等提供很好的隔离性和安全性。首先解释了什么是CLR Hosting,什么是AppDomain,如何加载卸载监视AppDomain,然后讲了宿主怎样使用AppDomain,最后讲了高级的宿主控制方法以及如何写出健壮的宿主应用程序。
posted @ 2010-05-21 15:50  bengxia  阅读(627)  评论(0编辑  收藏  举报
无觅相关文章插件,快速提升流量