- 你所在位置:首页 〉VS.net〉C#〉C#高级编程(4版)〉1.3 C#高级编程:详细介绍中间语言(2)
- 1.3 C#高级编程:详细介绍中间语言(2)
- 作者:佚名 文章来源:http://book.csdn.net/ 发布日期:2007-11-10 浏览次数:532
-
- 打印这篇文章
-
4. 应用程序域
应用程序域是.NET中的一个重要技术改进,它用于减少运行应用程序的系统开销,这些应用程序需要与其他程序分离开来,但同时还需要彼此通信。典型的例子是Web服务器应用程序,它需要同时响应许多浏览器请求。因此,要有许多组件实例同时响应这些同时运行的请求。
在.NET没有开发出来前,可以让这些实例共享同一个进程,但此时一个运行的实例就有可能导致整个网站的崩溃;也可以把这些实例孤立在不同的进程中,但这样做会增加相关性能的系统开销。
到现在为止,孤立代码的惟一方式是通过进程来实现的。在运行一个新的应用程序时,它会在一个进程环境内运行。Windows通过地址空间把进程分隔开来。这样,每个进程有4GB的虚拟内存来存储其数据和可执行代码(4GB对应于32位系统,64位系统要用更多的内存)。Windows利用额外的间接方式把这些虚拟内存映射到物理内存或磁盘空间的一个特殊区域中,每个进程都会有不同的映射,虚拟地址空间块映射的物理内存之间不能有重叠,这种情况如图1-2所示。

图 1-2
在一般情况下,任何进程都只能通过指定虚拟内存中的一个地址来访问内存——即进程不能直接访问物理内存,因此一个进程不可能访问分配给另一个进程的内存。这样就可以确保任何执行出错的代码不会损害其地址空间以外的数据(注意在Windows 95/98上,这些保护措施不像在Windows NT/2000/XP/2003上那样强大,所以理论上存在应用程序因写入不对应的内存而导致Windows崩溃的可能性)。
进程不仅是运行代码的实例相互隔离的一种方式,在Windows NT/2000/XP/2003系统上,它们还可以构成分配了安全权限和许可的单元。每个进程都有自己的安全标识,明确地表示Windows允许该进程可以执行的操作。
进程对确保安全有很大的帮助,而它们的一大缺点是性能。许多进程常常在一起工作,因此需要相互通信。一个常见的例子是进程调用一个COM组件,而该COM组件是可执行的,因此需要在它自己的进程上运行。在COM中使用代理时也会发生类似的情况。因为进程不能共享任何内存,所以必须使用一个复杂的编组过程在进程之间复制数据。这对性能有非常大的影响。如果需要使组件一起工作,但不希望性能有损失,惟一的方法是使用基于DLL的组件,让所有的组件在同一个地址空间中运行—— 其风险是执行出错的组件会影响其他组件。
应用程序域是分离组件的一种方式,它不会导致因在进程之间传送数据而产生的性能问题。其方法是把任何一个进程分解到多个应用程序域中,每个应用程序域大致对应一个应用程序,执行的每个线程都运行在一个具体的应用程序域中,如图1-3所示。

图 1-3
如果不同的可执行文件都运行在同一个进程空间中,显然它们就能轻松地共享数据,因为理论上它们可以直接访问彼此的数据。虽然在理论上这是可以实现的,但是CLR会检查每个正在运行的应用程序的代码,以确保这些代码不偏离它自己的数据区域,保证不发生直接访问其他进程的数据的情况。这初看起来是不可能的,如何告诉程序要做什么工作,而又不真正运 行它?
实际上,这么做通常是可能的,因为中间语言拥有强大的类型安全功能。在大多数情况下,除非代码明确使用不安全的特性,例如指针,否则它使用的数据类型可以确保内存不会被错误地访问。例如,.NET数组类型执行边界检查,以禁止执行超出边界的数组操作。如果运行的应用程序的确需要与运行在不同应用程序域中的其他应用程序通信或共享数据,就必须调用.NET的远程服务。
被验证不能访问超出其应用程序域的数据(而不是通过明确的远程机制)的代码就是内存类型安全的代码,这种代码与运行在同一个进程中但应用程序域不同的类型安全代码一起运行是安全的。
1.3.4 通过异常方法处理错误
.NET Framework可以根据异常使用相同的机制处理错误情况,这与Java和C++是一样的。C++开发人员应注意到,由于IL有非常强大的类型系统,所以在IL中以C++的方式使用异常不会带来相关的性能问题。另外,.NET和C#也支持finally块,这是许多C++开发人员长久以来的愿望。
第12章会详细讨论异常。简要地说,代码的某些领域被看作是异常处理程序例程,每个例程都能处理某种特殊的错误情况(例如,找不到文件,或拒绝执行某些操作的许可)。这些条件可以定义得很宽或很窄。异常结构确保在发生错误情况时,执行进程立即跳到异常处理程序例程上,处理错误情况。
异常处理的结构还提供了一种方便的方式,当对象包含错误情况的准确信息时,该对象就可以传送给错误处理例程。这个对象包括给用户提供的相应信息和在代码的什么地方检测到错误的确切信息。
大多数异常处理结构,包括异常发生时的程序流控制,都是由高级语言处理的,例如C#、Visual Basic 2005和C++,任何中间语言命令都不支持它。例如,C#使用try{}、catch{}和 finally{}代码块来处理它,详见第12章。
.NET提供了一种基础结构,让面向.NET的编译器支持异常处理。特别是它提供了一组.NET类来表示异常,语言的互操作性则允许错误处理代码处理被抛出的异常对象,无论错误处理代码使用什么语言编写,都是这样。语言的无关性没有体现在C++和Java的异常处理中,但在COM的错误处理机制中有一定限度的体现。COM的错误处理机制包括从方法中返回错误代码以及传递错误对象。在不同的语言中,异常的处理是一致的,这是多语言开发的重要一环。
1.3.5 特性的使用
特性(attribute)是使用C++编写COM组件的开发人员很熟悉的一个功能(使用Microsoft的COM接口定义语言(Interface Definition Language,IDL))。特性最初是为了在程序中提供与某些项相关的额外信息,以供编译器使用。
.NET支持特性,因此现在C++、C#和Visual Basic 2005也支持特性。但在.NET中,对特性的革新是建立了一个机制,通过该机制可以在源代码中定义自己的特性。这些用户定义的特性将和对应数据类型或方法的元数据放在一起,这对于文档说明书十分有用,它们和反射技术一起使用,以根据特性执行编程任务。另外,与.NET的语言无关性的基本原理一样,特性也可以在一种语言的源代码中定义,而被用另一种语言编写的代码读取。
本书的第11章详细介绍了特性。
- 打印这篇文章
- 与本文主题相关的文章
- 返回首页
