Microsoft NET 框架常见问题Word文档下载推荐.docx
《Microsoft NET 框架常见问题Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Microsoft NET 框架常见问题Word文档下载推荐.docx(9页珍藏版)》请在冰豆网上搜索。
VisualBasic®
或标准Microsoft®
Win32®
)方面都具有更大的优势。
当然,如果您是开发Web站点,那么从ASP.NET开始,您就会感受到.NET框架的强大吸引力。
从何处可以获得.NET框架SDK?
现在可以从MSDNOnlineDownloads(英文)下载.NET框架SDK的Beta1版。
鉴于其大小,我们以多种方式提供此Beta版:
作为一个下载文件(106MB),分为11部分下载,或者从MicrosoftDeveloperStore定购其CD:
美国/加拿大(英语)
国际(英语)
.NET框架可以运行于哪些平台?
Beta1版可以运行在Microsoft®
Windows®
2000、Windows95/98/ME和WindowsNT®
4.0上。
另外,还有一个称为.NET精简框架的.NET框架版本。
它用于使蜂窝电话和增强型电视等设备也具有.NET框架的某些功能。
.NET精简框架将运行在WindowsCE和其他嵌入式操作系统上。
.NET框架支持哪些编程语言?
.NET框架与编程语言无关。
事实上任何语言都可以支持.NET框架。
目前,您可以用许多语言来创建.NET程序,包括:
C++、Microsoft®
VisualBasic.NET、JScript®
和Microsoft的最新语言——C#。
以后,也会有大量的第三方语言可以用来创建.NET框架应用程序,包括COBOL、Eiffel、Perl、Python、Smalltalk等等。
.NET框架和COM+服务之间是什么关系?
在.NET框架中,不仅可以完全访问COM+服务,而且也更容易创建服务组件。
.NET框架组件可被添加至COM+应用程序中。
在COM+应用程序中,.NET框架组件可以利用自动组件服务,例如:
事务、对象池、排队组件、事件等等。
.NET框架和DCOM之间是什么关系?
DCOM是用于进程间通讯的COM基础结构。
.NET框架支持大量用于进程间通讯的可插入通道和格式化程序。
在托管代码和非托管代码之间进行转换时,.NET框架使用了COM基础结构,尤其是DCOM。
所有使用COM+服务的方案都使用了托管到非托管转换,因此默认使用DCOM。
对于注重互操作性的进程间通讯,.NET框架也支持SOAP(简单对象访问协议)。
.NET框架是否仅仅是WindowsDNA的新名称?
不。
WindowsDNA是用于创建紧耦合的分布式Web应用程序的一种体系结构。
由于分布式应用程序变得需要更多的松耦合原理,因此Microsoft在.NET中发展了该体系结构。
.NET框架是.NET体系结构的一部分。
运行时技术问题
术语
什么是公共语言运行时(CLR)?
公共语言运行时是.NET框架应用程序的执行引擎。
它提供许多服务,包括:
代码管理(加载和执行)
应用程序内存隔离
类型安全验证
IL到本机代码的转换
元数据(增强的类型信息)访问
为托管对象管理内存
强制代码访问安全
异常处理,包括跨语言异常
托管代码、COM对象和现有DLL(非托管代码和数据)之间的互操作
自动进行对象布局
对开发人员服务(配置、调试等)的支持
什么是公共类型系统(CTS)?
公共类型系统是多信息类型系统,它被内置在公共语言运行时中,支持大多数编程语言中的类型和操作。
公共类型系统支持大量编程语言的完全实现。
什么是公共语言规范(CLS)?
公共语言规范是一组结构和限制,用作库编写者和编译器编写者的指南。
它使任何支持CLS的语言都可以完全使用库,并且使这些语言可以相互集成。
公共语言规范是公共类型系统的子集。
对于那些需要编写代码供其他开发人员使用的应用程序开发人员,公共语言规范也非常重要。
如果开发人员遵循CLS规则来设计公共访问的API,那么就可以在支持公共语言运行时的任何其他编程语言中很容易地使用这些API。
什么是Microsoft中间语言(MSIL)?
MSIL是与CPU无关的指令集。
.NET框架程序被编译成MSIL。
它包含加载、存储、初始化和调用对象方法的指令。
与元数据和公共类型系统结合,MSIL允许真正的跨语言集成。
MSIL在执行前被转换为机器代码,而不是一边解释一边执行。
什么是托管代码和托管数据?
托管代码是编写为支持公共语言运行时服务的代码(请参阅“什么是公共语言运行时?
”)。
为了支持这些服务,代码必须向运行时提供最小级别的信息(元数据)。
默认情况下,所有C#、VisualBasic.NET和JScript.NET代码都是托管代码。
VisualStudio.NETC++代码在默认情况下不是托管代码,但通过指定命令行开关(/CLR),编译器也可以生成托管代码。
与托管代码密切相关的是托管数据。
托管数据是由公共语言运行时的垃圾回收器进行分配和释放的数据。
默认情况下,C#、VisualBasic和JScript.NET数据是托管数据。
不过,通过使用特殊的关键字,C#数据可以被标记为非托管数据。
VisualStudio.NETC++数据在默认情况下是非托管数据(即使在使用/CLR开关时),但是在使用C++的托管扩展时,可以使用“__gc”关键字将类标记为托管类。
就象该名称所显示的那样,它表示类实例的内存由垃圾回收器管理。
另外,该类也完全成为.NET框架的成员,同时具备它所带来的好处和限制。
好处的一个例子是:
它可以与其他语言编写的类正确地进行互操作(如托管的C++类可以从VisualBasic类继承);
限制的一个例子是:
托管类只能从一个基类继承。
程序集
什么是程序集?
程序集是.NET框架应用程序的主要构造块。
它是作为一个单一实现单元(包含一个或多个文件)来创建、标识和部署的功能集合。
所有的托管类型和资源都可以被标记为仅在其实现单元内访问,或者标记为可由该单元以外的代码来访问。
程序集通过清单来进行自我说明。
清单是每个程序集的不可或缺的组成部分。
清单:
建立程序集标识(以文本名称的格式)、版本、类别和数字签名(如果要在应用程序之间共享该程序集)。
定义组成程序集实现的文件(通过名称和文件散列)。
指定组成程序集的类型和资源,包括哪些是从程序集中导出的。
逐条记录编译时对其他程序集的依存。
指定程序集正确运行所需要的权限的集合。
此信息在运行时用于解析引用、强制版本绑定策略以及验证所加载的程序集的完整性。
因为每一类型都被加载到程序集的上下文中,所以运行时可以确定并定位任何正在运行的对象的程序集。
程序集也是应用了代码访问安全权限的单元。
在确定授予其所包含的代码哪些权限时,每个程序集的标识证据都被认为是独立的。
程序集的自我说明特征也有助于实现无影响安装和XCOPY部署。
什么是专用程序集和共享程序集?
专用程序集仅由单一应用程序使用,并且存储在该应用程序的安装目录中(或其子目录中)。
共享程序集是可被多个应用程序引用的程序集。
要共享一个程序集,该程序集必须明确为这个目的而创建,这可以通过给其指定加密的增强型名称(用作共享名称)来实现。
相反,专用程序集名称只要求在使用它的应用程序中是唯一的。
通过区分专用和共享程序集,我们介绍明确决定共享的要点。
只需简单地将专用程序集部署在应用程序目录中,即可确保应用程序只在创建和部署它的那部分中运行。
对专用程序集的引用只在专用应用程序目录内部进行解析。
选择创建和使用共享程序集可以有多种原因,例如表达版本策略的能力。
共享程序集具有加密的增强型名称,这项事实意味着只有程序集的作者才拥有密钥来生成程序集的新版本。
因此,如果您做出策略声明,希望接受程序集的新版本,则您可以确信版本更新将由作者来控制和验证。
否则,您就不会接受它们。
对于在本地安装的应用程序,共享程序集通常被明确安装在全局程序集缓存中(程序集的本地缓存由.NET框架维护)。
.NET框架的版本管理特性的关键在于下载的代码不会影响本地安装的应用程序的执行。
下载的代码被放在一个特殊的下载缓存中,即使某些下载组件被编译为共享程序集,也不能在机器上全局使用这些代码。
与.NET框架一起发布的类都被编译为共享程序集。
如果我想创建一个共享程序集,在标记和管理密钥对方面是否需要额外的开销?
创建共享程序集确实涉及到加密密钥方面的工作。
创建程序集时,只有公共密钥是必要的。
支持.NET框架的编译器提供命令行选项(或使用自定义属性),用于在创建程序集时提供公共密钥。
通常在资源数据库中保留一份常用的公共密钥,并使编译脚本指向此密钥。
在发布程序集之前,必须使用相应的私人密钥将其完全标记。
这是通过SDK工具SN.exe(增强型名称)来完成的。
增强型名称标记不象Authenticode一样需要使用证书。
它不涉及第三方组织,不需要付费,也不受证书约束。
另外,验证增强型名称的额外开销远远小于验证Authenticode的开销。
不过,增强型名称不会生成任何信任某个出版商的语句。
增强型名称使您可以确信给定程序集的内容没有被篡改,在运行时为您加载的程序集来自于您开发时针对的出版商。
但它不会生成有关是否信任出版商身份的语句。
名称空间与程序集名称之间有什么区别?
名称空间是类型的一种逻辑命名方案,其中简单类型名称(如MyType)前面带有用点分隔的层次结构名称。
这样的命名方案完全在开发人员的控制之下。
例如,键入MyCompany.FileAccess.A和MyCompany.FileAccess.B在逻辑上将会具有与文件访问相关的功能。
.NET框架使用一种层次结构命名方案,用于将类型按相关功能的逻辑类别进行分组,例如,ASP.NET应用程序框架或远程处理功能。
设计工具可以利用名称空间使开发人员更容易在代码中浏览和引用类型。
名称空间的概念与程序集的概念之间没有任何联系。
一个程序集可以包含其层次结构名称具有不同名称空间根的类型,而一个逻辑名称空间根可以跨越多个程序集。
在.NET框架中,名称空间是在设计时进行逻辑命名的便捷方式,而程序集在运行时为类型建立名称作用域。
应用程序部署和隔离
部署.NET应用程序时可以使用哪些选项?
通过使应用程序的无影响安装和XCOPY部署成为可能,.NET框架简化了部署。
因为所有的请求首先在专用应用程序目录中进行解析,所以只需简单地将一个应用程序的目录文件复制到磁盘中,即可运行该应用程序,而不需要注册。
此方案对于Web应用程序、Web服务和独立的桌面应用程序特别有吸引力。
不过,在有些方案中XCOPY还不足以担当分发机制。
例如,当应用程序具有很少的专用代码,而依赖于可用的共享程序集;
或者应用程序不是安装在本地(而是按需下载)。
对于这些情况,.NET框架提供了扩展的代码下载服务以及与WindowsInstaller的集成。
.NET框架提供的代码下载支持通过当前平台提供了许多优势,包括增量下载、代码访问安全性(不再有“Authenticode”对话框)和应用程序隔离(为一个应用程序下载的代码不会影响其他应用程序)。
WindowsInstaller是.NET应用程序可以使用的另外一个强大的部署机制。
在WindowsInstaller1.5中,WindowsInstaller的所有特性(包括发行、公布和应用程序修补)都可以在.NET应用程序中使用。
如果我已经编写了一个程序集,并希望在多个应用程序中使用它,我应该在何处部署它?
要由多个应用程序使用的程序集(如共享程序集)需要部署到全局程序集缓存中。
在预发布版和Beta版中,使用AlinkSDK工具的/i选项可将程序集安装到缓存中:
al/i:
myDll.dll
WindowsInstaller的后续版本能够将程序集安装到全局程序集缓存中。
如何才能看到在全局程序集缓存中安装了哪些程序集?
.NET框架附带了一个Windows外壳扩展,用于查看程序集缓存。
在Windows资源管理器中,转至%windir%\assembly以激活查看器。
什么是应用程序域?
应用程序域(通常是AppDomain)是用于隔离应用程序的虚拟进程。
在同一个应用程序作用域中创建的所有对象(换句话说,从该应用程序的入口点开始沿着对象激活序列的任何地方)都在同一个应用程序域中创建。
多个应用程序域可以存在于一个操作系统进程中,使它们成为隔离应用程序的简便方式。
操作系统进程通过使用各不相同的内存地址空间来提供隔离。
尽管它是有效的,但也是代价昂贵的,并且不能达到大型Web服务器所需要的数量。
与其相比,公共语言运行时通过管理在应用程序域中运行的代码的内存使用来强制进行应用程序隔离。
这样就确保它不会访问应用程序域以外的内存。
需要注意的是,只有类型安全的代码才能以这种方式管理(当在应用程序域中加载不安全代码时,运行时不能保证隔离)。
垃圾回收
什么是垃圾回收?
垃圾回收是使计算机能检测何时不再能够访问某个对象的一种机制。
它将自动释放由该对象使用的内存(也调用用户编写的称为“结束者”的清理例程)。
一些垃圾回收器(如由.NET使用的)会压缩内存,并因此减少程序的工作集。
非确定性垃圾回收是如何影响代码的?
对于大多数编程人员而言,拥有一个垃圾回收器(并且使用可作为垃圾回收的对象)意味着永远不需要操心释放内存或引用计数对象,即使您使用了复杂的数据结构。
但如果您通常在同一个用于释放对象内存的代码块中释放系统资源(文件句柄、锁定等等),那么在编码样式方面需要做一些修改。
使用可作为垃圾回收的对象时,您应该提供一种方法,来明确释放系统资源(也就是说,由您的程序控制),同时允许垃圾回收器在压缩工作集时释放内存。
是否能够避免使用可作为垃圾回收的堆?
所有支持运行时的语言都允许您从可作为垃圾回收的堆中分配类对象。
这在快速分配方面带来了好处,并且使编程人员无需自己来计算何时应该显式“free”每个对象。
CLR还提供了ValueTypes对象——它们与类相似,但ValueType对象是在运行时堆栈(不是堆)中分配的,因此当您的代码退出定义这些对象的过程时,将自动回收它们。
这就是C#中“struct”的操作方式。
C++的托管扩展使您可以选择类对象分配的位置。
如果使用__gc关键字声明为托管类,它们将从可作为垃圾回收的堆中分配;
如果它们不包含__gc关键字,它们将与普通的C++对象一样从C++堆中分配,并且使用“free”方法显式释放。
有关垃圾回收的的详细信息,请参阅:
垃圾回收:
Microsoft.NET框架中的自动内存管理(英文)
垃圾回收-第2部分:
Microsoft.NET框架中的自动内存管理(英文)
远程处理
如何在公共语言运行时中进行进程内和进程间通讯?
进程内通讯有两种:
在单一应用程序域的上下文中,或者跨应用程序域。
在同一个应用程序域的上下文中,使用代理作为监听机制,而不涉及封送处理/序列化。
当跨应用程序域时,使用运行时二进制协议来作封送处理/序列化。
进程间通讯为每个特定目的使用一个可插入通道和格式化程序协议。
如果开发人员使用soapsuds.exe工具指定终结点来生成元数据代理,那么默认值是带有SOAP格式化程序的HTTP通道。
如果开发人员在托管世界中执行显式远程处理,需要明确指定使用的通道和格式化程序。
这可以通过配置文件用可管理的方式来表示,或者用API调用来加载特定通道。
选项如下:
带有SOAP格式化程序的HTTP通道(HTTP在Internet上或任何必须通过防火墙进行通信的时候运行良好)
带有二进制格式化程序的TCP通道(对于局域网,TCP是性能较高的选项)
带有SOAP格式化程序的SMTP通道(仅对跨计算机有意义)
在托管代码和非托管代码之间进行转换时,COM基础结构(尤其是DCOM)用于远程处理。
在CLR的中间版本中,这也适用于服务组件(使用COM+服务的组件)。
在最终版本中,配置任何远程组件都是可能的。
对象的分布式垃圾回收由名为“租用生存期”的系统来管理。
每个对象都有一个租用时间,当到期时,该对象与CLR的远程处理基础结构断开连接。
对象具有一个默认的更新时间——当客户端成功地调用了对象时,租用将被更新。
客户端可以显式更新租用。
互操作性
是否可以在.NET框架程序中使用COM对象?
是。
您现在部署的任何COM组件都可以在托管代码中使用。
通常情况下,所需的调整是完全自动进行的。
特别是,可以使用运行时可调用包装(RCW)从.NET框架访问COM组件。
此包装将COM组件提供的COM接口转换为与.NET框架兼容的接口。
对于OLE自动化接口,RCW可以从类型库中自动生成;
对于非OLE自动化接口,开发人员可以编写自定义RCW,手动将COM接口提供的类型映射为与.NET框架兼容的类型。
是否可以在COM程序中使用.NET框架组件?
您现在创建的托管类型都可以通过COM访问。
通常情况下,所需的配置是完全自动进行的。
托管开发环境的某些新特性不能在COM中访问。
例如,不能在COM中使用静态方法和参数化构造函数。
一般,提前确定给定类型所针对的用户是一种较好的办法。
如果类型需要在COM中使用,您将被限制在使用COM可访问的特性。
默认情况下,托管类型可能是可见的,也可能是不可见的,这由用于编写托管类型的语言决定。
特别是,可以使用COM可调用包装(CCW)从COM访问.NET框架组件。
这与RCW(请参阅上一个问题)相似,但它们的方向相反。
同样,如果.NET框架开发工具不能自动生成包装,或者如果自动方式不是您所需要的,则可以开发自定义的CCW。
是否可以在.NET框架程序中使用Win32API?
使用P/Invoke,.NET框架程序可以通过静态DLL入口点的方式来访问本机代码库。
下面是C#调用Win32MessageBox函数的示例:
usingSystem;
usingSystem.Runtime.InteropServices;
classMainApp
{
[DllImport("
user32.dll"
EntryPoint="
MessageBox"
)]
publicstaticexternintMessageBox(inthWnd,StringstrMessage,StringstrCaption,uintuiType);
publicstaticvoidMain()
MessageBox(0,"
您好,这是PInvoke!
"
"
.NET"
0);
}
}
安全性
如何使代码与安全系统协调工作?
通常,这不成问题——大多数应用程序能安全地运行,不会受恶意攻击的干扰。
通过简单地使用标准类库来访问资源(如文件)或执行受保护的操作(例如反转类型的私有成员),安全性由这些库来实施。
应用程序开发者需要完成的一项简单工作是包括权限请求(一种公开的安全性),将代码可能接收的权限限制在它所需要的权限范围内。
这也确保了如果代码被允许运行,它在运行时将具有所需的所有权限。
仅当开发人员需要编写提供新型资源的新基类库时,他们才需要直接处理安全系统。
在这种情况下,并非所有的代码都有潜在的安全性问题,代码访问安全机制将其限制在替代了安全系统的那部分代码上。
为什么在网络共享驱动器中运行代码时会发生安全异常?
默认安全策略仅给来自本地Intranet区域的代码授予有限的权限。
这个区域是由InternetExplorer安全设置定义的,它们应该配置为与企业内部的本地网络相匹配。
由于由UNC或映射驱动器(例如使用NETUSE命令)命名的文件都需要在本地网络上发送,因此它们也在本地Intranet区域中。
默认值是为不安全的Intranet这种最坏情况而设置的。
如果您的Intranet比较安全,您可以修改安全策略(用CASPol工具),给本地Intranet或其一部分(例如特定的计算机共享名)授予更多的权限。
如何编写代码,使它在安全系统停止该代码时运行?
当代码试图执行XX的操作时,将发生安全异常。
权限是基于代码(尤其是其位置)来授予的。
例如,从Internet中运行的代码所得到的权限比在本地计算机上运行的代码所得到的权限要少,这是因为经验证明,它的可靠性要低一些。
因此,要运行由于安全异常而失败的代码,您必须增加授予它的权限。
一个简单的方法是将代码移到更受信任的位置(例如本地文件系统)。
但这种方法并不是在任何情况下都有效(Web应用程序是一个很好的例子,企业网络上的Intranet应用程序是另一个例子)。
因此,不要改变代码位置,而是通过更改安全策略给该位置授予更多的权限。
请使用代码访问安全策略工具(caspol.exe)或图形化管理工具(在Beta2和更高版本中可以得到)来执行此操作。
如果您是代码的开发人员或发行者,您也可以对它进行数字签名,然后修改安全策略,给带有该数字签名的代码授予更多权限。
但是,在执行上述任何操作时,请记住此代码被授予较少的权限,是因为它不是来自受信任的来源——在将代码移至本地计算机或更改安全策略以前,您应该确