每种应用程序都需要使用一段名为运行库宿主的代码才能启动。运行库宿主会将运行库加载到一个进程中,在该进程中创建应用程序域,然后在这些应用程序域内加载并执行用户代码。宿主概述.NET 框架附带了支持几种常见情况的运行库宿主,其中包括 ASP.NET 所使用的宿主和 Microsoft Internet Explorer 所使用的宿主。.NET 框架 SDK 还提供了一种非托管 API,它可用于编写自定义的运行库宿主。例如,您可以为应用程序服务器产品编写自定义的运行库宿主,以用于同时运行来自多个用户的代码。利用自定义的运行库宿主,应用程序服务器的客户可以编写托管代码,这些代码将具有高度可缩放性、通用类型系统、多语言支持、自动内存管理等优点。如果将调试器等专用工具用作运行库宿主,它们就可以访问诸如在进程中运行的应用程序域列表等信息。大多数运行库宿主都包括非托管代码和托管代码。非托管宿主代码将在进程开始时将运行库加载到进程中。当运行库加载到进程中后,就可以将控制权转移给宿主代码的托管部分,从而提高性能。通过实现宿主中与托管代码中的用户代码进行交互的部分,可获得更好的性能,因为宿主代码对用户代码的调用是在托管环境中进行的。如果用非托管代码来编写整个宿主,那么每当宿主代码与用户代码进行交互时,都需要将非托管代码转换为托管代码。非托管宿主代码用于配置公共语言运行库,将其加载到进程中,并将程序转换为托管代码。而宿主代码的托管部分将创建用户代码运行时所在的应用程序域,并将用户请求调度给所创建的应用程序域。将运行库加载到进程中执行任何托管代码之前,宿主必须首先加载并初始化公共语言运行库。由于此时运行库尚未在进程中运行,所有宿主都将用非托管的 Stub 启动。.NET 框架提供了一组名为宿主 API 的非托管 API,宿主可以利用它们来启动运行库。有关更多信息,请参阅 .NET 框架 SDK 的《工具开发人员指南》中的公共语言运行库宿主接口规范。为了将运行库加载到进程中,宿主将调用 CorBindToRuntimeEx,它位于 .NET 框架 SDK 的公共语言运行库宿主接口规范中。CorBindToRuntimeEx 的原型位于 .NET 框架 SDK 的“Include”目录下的 Mscoree.h 中。当调用 CorBindToRuntimeEx 时,宿主可以设置相应的值,以控制所加载的运行库版本和基本功能(如垃圾回收和程序集加载)的行为。宿主可以设置下表中所列的值。值说明并行垃圾回收指定垃圾回收是在后台线程上进行还是在运行用户代码的线程上进行。 有关更多信息,请参阅 .NET 框架 SDK 的《工具开发人员指南》中的公共语言运行库宿主接口规范。加载程序优化控制是否以非特定于域的方式来加载程序集。如果以非特定于域的方式加载程序集,一个进程中的所有应用程序域就能够共享程序集代码和只读运行库数据结构。服务器与工作站指定是加载工作站内部版本还是服务器内部版本。 有关更多信息,请参阅 .NET 框架 SDK 《工具开发人员指南》中的公共语言运行库宿主接口规范。版本指定将加载到进程中的运行库版本。除了在调用 CorBindToRuntimeEx 时设置上表所述的值之外,宿主还可以请求指向 IcorRuntimeHost 的接口指针。利用该指针,宿主可以完成诸如设置配置选项和转换为托管宿主代码等任务,以创建应用程序域并执行用户代码。宿主可以使用 IcorRuntimeHost 来配置运行库的各个方面(如垃圾回收),以将其加载到进程中或注册附加的事件。例如,宿主可以使用 GetConfiguration 来注册回调函数(当特定线程将要在调试器中停止时,该函数会收到通知)或指定垃圾回收堆的大小。ICorRuntimeHost 还提供了 Start 和 Stop 方法,使宿主能够显式地控制运行库在进程中的生存期。当第一个托管代码在进程中运行时,将隐式调用 Start;当关闭进程时,将隐式调用 Stop。虽然宿主无需(通常也不会)显式调用这些方法,但在某些情况下,这样做还是有用的。例如,当宿主运行完托管代码,需要为节省内存和其他资源而从进程中卸载运行库时,它就可能需要显式调用这些方法。转换为托管宿主代码当加载并初始化运行库后,宿主必须从非托管代码转换为托管代码,以便执行托管宿主代码和用户代码。托管宿主代码通常在默认应用程序域中运行。每当运行库初始化时,它都将自动创建默认应用程序域。当关闭进程时,将卸载默认的应用程序域。大多数宿主都不在默认应用程序域中运行用户代码,因为它无法独立于进程关闭。要转换为托管代码,宿主必须获取指向默认应用程序域的指针,然后将宿主的托管部分加载到该域中。当完成向托管代码的转换后,宿主的托管部分可以创建其他应用程序域,以查找用户代码或更多的宿主代码。通过调用 ICorRuntimeHost::GetDefaultDomain,宿主可以获取指向默认应用程序域的接口指针。此调用将返回指向 System. AppDomain(表示默认应用程序域)实例的指针。接口指针的类型为 _AppDomain。简而言之 猜你喜欢