扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
一、Emit概述
让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:申请域名、网页空间、营销软件、网站建设、廉江网站维护、网站推广。
Emit,可以称为发出或者产生。在Framework中,与Emit相关的类基本都存在于System.Reflection.Emit命名空间下。可见Emit是作为反射的一个元素存在的。说道反射,大家应该都不陌生,它允许我们查看程序集的元素据,从而取得形如程序集包含哪些类型,类型包含哪些方法等等大量的信息。但是反射也仅能够‘看’,而Emit则可以在运行时动态生成代码。接下来就来看看如何用Emit生成代码。
二、动态生成代码
首先需要明确的是这里的代码并不是我们时常提到的C#,VB等源代码,而是IL代码。既然是IL代码,那学习Emit是不是要先对IL很熟悉呢?诚然,熟悉IL代码对Emit学习会大有帮助,但是不懂也没关系,因为IL和高级语言一样,也是有一些相对固定的语法结构组成,不可能在一个IL程序里表述if是一个样子而到另一个程序却变成了另一个样子。所以只要多用,多记,很快就能掌握这些东西。
其次如C#,VB等程序会包含程序集,模块,类,方法,属性等元素一样,Emit生成的代码也包括这些元素。以下介绍Emit生成代码的基本流程:
1.构建程序集
在创建程序集之前,我们先要为它取个名字。
var asmName = new AssemblyName("Test");
AssemblyName位于System.Reflection命名空间下,它代表程序集的名称。
然后我们就可以用上面的名字来创建一个程序集了:
var asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
AssemblyBuilderAccess.ReflectionOnly:
DefineDynamicAssembly有很多重载,比如上面的例子可以添加第三个参数用于作为生成的程序集要存放到的目录。关于其他重载形式,大家可以查阅MSDN。这里重点说说AssemblyBuilderAccess这个枚举。
它有以下几个值:
AssemblyBuilderAccess.ReflectionOnly:表示动态程序集只能用于反射获取元素据用,不能执行。
AssemblyBuilderAccess.Run:表示动态程序集是用于执行的。 AssemblyBuilderAccess.Save:表示动态程序集会被保存到磁盘上,不能立即执行。 AssemblyBuilderAccess.RunAndSave:表示动态程序集会被保存至磁盘并能立即执行。
2.创建模块
创建程序集后,就需要为程序集添加模块了,我们可以如下定义一个模块:
var mdlBldr = asmBuilder.DefineDynamicModule("Main", "Main.dll");
如果想把动态生成的程序集保存至磁盘(如本例),定义模块时模块所在文件的名称一定要和保存程序集(后面会提到)时提供的文件名称一样。
3.定义类
有了前面的准备工作,我们开始定义我们的类型:
var typeBldr = mdlBldr.DefineType("Hello",TypeAttributes.Public);
DefineType还可以设置要定义的类的基类,要实现的接口等等。
4.定义类成员(方法,属性等等)
既然有了类,下面我们就为它添加一个SayHello方法吧:
var methodBldr = typeBldr.DefineMethod(
"SayHello",
MethodAttributes.Public,
null,//return type
null//parameter type );
该方法的原型为public void SayHell();
方法签名已经生成好了,但方法还缺少实现。在生成方法的实现前,必须提及一个很重要的概念:evaluation stack。在.Net下基本所有的操作都是通过入栈出栈完成的。这个栈就是evaluation stack。比如要计算两个数(a,b)的和,首先要将a放入evaluation stack中,然后再将b也放入栈中,最后执行加法时将弹出栈顶的两个元素也就是a和b,相加再将结果推送至栈顶。
Console.WriteLine("Hello,World")可以用Emit这样生成:
var il = methodBldr.GetILGenerator();//获取il生成器
il.Emit(OpCodes.Ldstr,"Hello, World");
il.Emit(OpCodes.Call,typeof(Console).GetMethod("WriteLine",new Type[]{typeof(string)}));
il.Emit(OpCodes.Ret);
OpCodes枚举定义了所有可能的操作,这里用到了:
ldStr:加载一个字符串到evaluation stack。
Call:调用方法。
Ret:返回,当evaluation stack有值时会返回栈顶值。
完成上面的步骤,一个类型好像就已经完成了。事实上却还没有,最后我们还必须显示的调用CreateType来完成类型的创建。
NET本身提供了强大的脚本引擎,可以直接使用.NETCLR的任何编程语言作为脚本语言,如VB.NET、C#、JScript,J#等等。使用脚本引擎,我们可以动态生成任意表达式、或动态导入任意脚本文件,并在任意时候执行。经实践发现,我们可以使用至少两种不同的方式在.NET中使用脚本引擎:VsaEngine和CodeDom。其实,CodeDom不能算是真正的脚本引擎,它实际上是编译器。但是我们完全可以利用CodeDom来模拟脚本引擎。使用Emit方法也能达到动态生成可执行代码的目的,而且Emit生成的代码不需要编译,因此速度更快。但是Emit插入的实际上是汇编代码,不能算是脚本语言。本文介绍如何以CodeDom方式来动态生成可执行代码。如何在.NET中实现脚本引擎(CodeDom篇)沐枫网志1.构造一个编译器设置编译参数编译参数需要在CompilerParameters设置:CompilerOptions用于设置编译器命令行参数IncludeDebugInformation用于指示是否在内存在生成AssemblyGenerateInMemory用于指示是否在内存在生成AssemblyGenerateExecutable用于指示生成的Assembly类型是exe还是dllOutputAssembly用于指示生成的程序文件名(仅在GenerateInMemory为false的情况)ReferencedAssemblies用于添加引用Assembly例如:theParameters.ReferencedAssemblies.Add("System.dll");创建指定语言的编译器编译需要由指定语言的CodeDomProvider生成。这里列举一些.NET的CodeDomProvider:vb.netMicrosoft.VisualBasic.VBCodeProviderC#Microsoft.CSharp.CSharpCodeProviderjscriptMicrosoft.JScript.JScriptCodeProviderJ#Microsoft.VJSharp.VJSharpCodeProvider以C#为例,要创建C#编译器,代码如下://.NET1.1/1.0ICodeCompilercompiler=newMicrosoft.CSharp.CSharpCodeProvider().CreateCompiler();//.NET2.0ICodeCompilercompiler=(ICodeCompiler)newMicrosoft.CSharp.CSharpCodeProvider();下面是完整的创建编译器的例子://////创建相应脚本语言的编译器///privatevoidcreateCompiler(stringstrLanguage,booldebugMode,stringstrAssemblyFileName){this.theParameters=newCompilerParameters();this.theParameters.OutputAssembly=System.IO.Path.Combine(System.IO.Path.GetTempPath(),strAssemblyFileName+".dll");this.theParameters.GenerateExecutable=false;this.theParameters.GenerateInMemory=true;if(debugMode){this.theParameters.IncludeDebugInformation=true;this.theParameters.CompilerOptions+="/define:TRACE=1/define:DEBUG=1";}else{this.theParameters.IncludeDebugInformation=false;this.theParameters.CompilerOptions+="/define:TRACE=1";}AddReference("System.dll");AddReference("System.Data.dll");AddReference("System.Xml.dll");strLanguage=strLanguage.ToLower();CodeDomProvidertheProvider;if("visualbasic"==strLanguage||"vb"==strLanguage){theProvider=newMicrosoft.VisualBasic.VBCodeProvider();if(debugMode)theParameters.CompilerOptions+="/debug:full/optimize-/optionexplicit+/optionstrict+/optioncompare:text/imports:Microsoft.VisualBasic,System,System.Collections,System.Diagnostics";elsetheParameters.CompilerOptions+="/optimize/optionexplicit+/optionstrict+/optioncompare:text/imports:Microsoft.VisualBasic,System,System.Collections,System.Diagnostics";AddReference("Microsoft.VisualBasic.dll");}elseif("jscript"==strLanguage||"js"==strLanguage){theProvider=newMicrosoft.JScript.JScriptCodeProvider();AddReference("Microsoft.JScript.dll");}elseif("csharp"==strLanguage||"cs"==strLanguage||"c#"==strLanguage){theProvider=newMicrosoft.CSharp.CSharpCodeProvider();if(!debugMode)theParameters.CompilerOptions+="/optimize";}//elseif("jsharp"==strLanguage||"vj"==strLanguage||"j#"==strLanguage)//{//theProvider=newMicrosoft.VJSharp.VJSharpCodeProvider();//if(!debugMode)//theParameters.CompilerOptions+="/optimize";//}elsethrownewSystem.Exception("指定的脚本语言不被支持。");this.theCompiler=theProvider.CreateCompiler();}//////添加引用对象。//////引用的文件名publicvoidAddReference(string__strAssemblyName){theParameters.ReferencedAssemblies.Add(__strAssemblyName);}注:在.NETFramework2.0中,由于CreateCompiler方法被标记作废。为避免产生编译警告,可直接返回CodeDomProvider作为编译器:this.theCompiler=(ICodeCompiler)theProvider;2.编译源代码编译源代码相当简单,只需一条语句就搞定了:CompilerResultscompilerResults=compiler.CompileAssemblyFromSource(this.theParameters,this.SourceText);执行后,可以从compilerResults取得以下内容:NativeCompilerReturnValue编译结果,用于检查是否成功Errors编译时产生的错误和警告信息CompiledAssembly如果编译成功,则返回编译生成的Assembly示例函数://////编译脚本。编译前将清空以前的编译信息。///CompilerInfo将包含编译时产生的错误信息。//////成功时返回True。不成功为False。publicboolCompile(){this.theCompilerInfo="";this.isCompiled=false;this.theCompiledAssembly=null;this.theCompilerResults=this.theCompiler.CompileAssemblyFromSource(this.theParameters,this.SourceText);if(this.theCompilerResults.NativeCompilerReturnValue==0){this.isCompiled=true;this.theCompiledAssembly=this.theCompilerResults.CompiledAssembly;}System.Text.StringBuildercompilerInfo=newSystem.Text.StringBuilder();foreach(CompilerErrorerrinthis.theCompilerResults.Errors){compilerInfo.Append(err.ToString());compilerInfo.Append("/r/n");}theCompilerInfo=compilerInfo.ToString();returnisCompiled;}3.执行代码使用Reflection机制就可以很方便的执行Assembly中的代码。我们假设编译时使用的脚本代码this.SourceText内容如下:namespacetest{publicclassscript{staticpublicvoidMain(){MessageBox.Show("Hello");}}}则相应的执行代码为:scriptEngine.Invoke("test.script","Main",null);Invoke函数内容://////执行指定的脚本函数(Method)。///如果指定的类或模块名,以及函数(Method)、或参数不正确,将会产生VsaException/VshException例外。//////类或模块名///要执行的函数(Method)名字///参数(数组)///返回执行的结果publicobjectInvoke(string__strModule,string__strMethod,object[]__Arguments){if(!this.IsCompiled||this.theCompiledAssembly==null)thrownewSystem.Exception("脚本还没有成功编译");Type__ModuleType=this.theCompiledAssembly.GetType(__strModule);if(null==__ModuleType)thrownewSystem.Exception(string.Format("指定的类或模块({0})未定义。",__strModule));MethodInfo__MethodInfo=__ModuleType.GetMethod(__strMethod);if(null==__MethodInfo)thrownewSystem.Exception(string.Format("指定的方法({0}::{1})未定义。",__strModule,__strMethod));try{return__MethodInfo.Invoke(null,__Arguments);}catch(TargetParameterCountException){thrownewSystem.Exception(string.Format("指定的方法({0}:{1})参数错误。",__strModule,__strMethod));}catch(System.Exceptione){System.Diagnostics.Trace.WriteLine(string.Format("执行({0}:{1})错误:{2}",__strModule,__strMethod,e.ToString()));returnnull;}}总结:CodeDom可以很方便的随时编译源代码,并动态执行。虽然作为脚本引擎,它没有VsaEngine正规和方便,但作为一般应用,也够用了。并且结合Reflection机制,它的功能比VsaEngine更强大:它可以编译任何提供CompilerProvider的CLR语言(目前.NET自带的语言中都有)。当然,它也有一些缺点:它生成的Assembly不能动态卸载。这在一般情况下不成问题,因为一个源代码只需编译一次,并载入执行,并不需要动态卸载。假如你需要做脚本编辑器时,就要考虑这个问题,因为有可能一个脚本会因为修修改改而不停的重新编译,从而造成不停的产生新的Assembly,最后将导致内存被大量占用。要解决这个问题,需要将编译器加载到独立的AppDomain中,通过卸载AppDomain达到卸载所需的Assembly的目的。
c# 是 java 和 C 混合的产物。
.NET Framework 类库是一个由 Microsoft .NET Framework SDK 中包含的类、接口和值类型组成的库。该库提供对系统功能的访问,是建立 .NET Framework 应用程序、组件和控件的基础。
DotNet FrameWork所有的类都包含在命名空间里面。
命名空间
.NET Framework 类库提供下列命名空间:
▲Microsoft.CSharp
包含支持用 C# 语言进行编译和代码生成的类。
▲Microsoft.JScript
包含支持用 JScript 语言进行编译和代码生成的类。
▲Microsoft.VisualBasic
包含支持用 Visual Basic .NET 语言进行编译和代码生成的类。
▲Microsoft.Vsa
包含使您可以将 .NET Framework 脚本引擎的脚本集成到应用程序中以及在运行时编译和执行代码的接口。
▲Microsoft.Win32
提供两种类型的类:处理由操作系统引发的事件的类和对系统注册表进行操作的类。
▲System
包含用于定义常用值和引用数据类型、事件和事件处理程序、接口、属性和处理异常的基础类和基类。
其他类提供支持下列操作的服务:数据类型转换,方法参数操作,数学计算,远程和本地程序调用,应用程序环境管理以及对托管和非托管应用程序的监管。
▲System.CodeDom
包含可用于表示源代码文档的元素和结构的类。这些元素可用于建立源代码文档的结构。通过使用 ▲System.CodeDom.Compiler 命名空间所提供的功能,可以将源代码文档输出为用受支持的语言编写的源代码。
▲System.CodeDom.Compiler
包含用于管理用受支持的编程语言生成和编译源代码的类型。每个代码生成器可根据“代码文档对象模型”(CodeDOM) 源代码模型的结构(由 ▲System.CodeDom 命名空间所提供的元素组成),用特定的某种编程语言生成源代码。
▲System.Collections
包含定义各种对象集合(如列表、队列、位数组、哈希表和字典)的接口和类。
▲System.Collections.Specialized
包含专用的强类型集合;例如,链接表词典、位向量以及只包含字符串的集合。
▲System.ComponentModel
提供用于实现组件和控件的运行时和设计时行为的类。此命名空间包括用于属性和类型转换器的实现、数据源绑定和组件授权的基类和接口。
▲System.ComponentModel.Design
包含可由开发人员用来生成自定义设计时组件行为和在设计时配置组件的用户界面的类。设计时环境提供了使开发人员能够安排组件并配置它们的属性的系统。
▲System.ComponentModel.Design.Serialization
提供支持在设计时自定义和控制序列化的类型。
▲System.Configuration
提供使您可以以编程方式访问 .NET Framework 配置设置和处理配置文件(.config 文件)中的错误的类和接口。
▲System.Configuration.Assemblies
包含用于配置程序集的类。
▲System.Configuration.Install
提供使您可以为自己的组件编写自定义安装程序的类。Installer 类是 .NET Framework 中所有自定义安装程序的基类。
▲System.Data
基本上由构成 ADO.NET 结构的类组成。ADO.NET 结构使您可以生成可用于有效管理多个数据源中的数据的组件。在断开连接的方案(如 Internet)中,ADO.NET 提供了一些可以在多层系统中请求、更新和协调数据的工具。ADO.NET 结构也可以在客户端应用程序(如 Windows 窗体)或 ASP.NET 创建的 HTML 页中实现。
▲System.Data.Common
包含由 .NET Framework 数据提供程序共享的类。.NET Framework 数据提供程序描述用于在托管空间中访问数据源(如数据库)的类的集合。
▲System.Data.Odbc
封装 ODBC .NET Framework 数据提供程序。.NET Framework 数据提供程序描述用于在托管空间中访问数据源(如数据库)的类的集合。通过使用 OdbcDataAdapter 类,可以填充驻留在内存中的 DataSet,使用它可以查询和更新数据源。
有关如何使用此命名空间的其他信息,请参见 OdbcDataReader、OdbcCommand 和 OdbcConnection 类。
注意:该命名空间仅在 .NET Framework 1.1 版中受支持。
▲System.Data.OleDb
封装 OLE DB .NET Framework 数据提供程序。OLE DB .NET Framework 数据提供程序描述了用于在托管空间中访问 OLE DB 数据源的类集合。
▲System.Data.OracleClient
封装 Oracle .NET Framework 数据提供程序。Oracle .NET Framework 数据提供程序描述了用于在托管空间中访问 Oracle 数据源的类集合。
注意:该命名空间仅在 .NET Framework 1.1 版中受支持。
▲System.Data.SqlClient
封装 SQL Server .NET Framework 数据提供程序。SQL Server .NET Framework 数据提供程序描述了用于在托管空间中访问 SQL Server 数据库的类集合。
▲System.Data.SqlServerCE
描述可用于在托管环境下从基于 Windows CE 的设备访问 SQL Server CE 中的数据库的类集合。通过此命名空间,可以在一个设备上创建 SQL Server CE 数据库,并且可以与另一个设备或远程服务器上的 SQL Server 数据库建立连接。
注意:该命名空间仅在 .NET Framework 1.1 版中受支持。
▲System.Data.SqlTypes
提供用于 SQL Server 中的本机数据类型的类。这些类提供了其他数据类型的更安全、更快速的替代物。使用此命名空间中的类有助于防止在可能发生精度损失的情况中出现的类型转换错误。由于其他数据类型与 SqlTypes 在后台相互转换,因此在此命名空间内显式创建和使用对象同样会产生较快的代码。
▲System.Diagnostics
提供允许与系统进程、事件日志和性能计数器进行交互的类。此命名空间还提供了使您可以调试应用程序和跟踪代码执行的类。有关更多信息,请参见 Trace 和 Debug 类。
▲System.Diagnostics.SymbolStore
提供使您可以读取和写入调试符号信息(如 Microsoft 中间语言 (MSIL) 映射的源行)的类。面向 .NET Framework 的编译器可以将调试符号信息存储到程序员的数据库 (PDB) 文件中。调试器和代码分析器工具可以在运行时读取调试符号信息。
▲System.DirectoryServices
提供从托管代码轻松访问 Active Directory 的方法。此命名空间包含两个组件类:DirectoryEntry 和 DirectorySearcher。这两个类使用 Active Directory 服务接口 (ADSI) 技术。ADSI 是由 Microsoft 提供的一组接口,是一种可灵活处理各种网络提供程序的工具。ADSI 使管理员能够相对轻松地查找和管理网络资源,不论网络规模有多大。
▲System.Drawing
提供对 GDI 基本图形功能的访问。▲System.Drawing.Drawing2D、▲System.Drawing.Imaging 和 ▲System.Drawing.Text 命名空间提供了更高级的功能。
▲System.Drawing.Design
包含扩展设计时用户界面 (UI) 逻辑和绘制的类。可以进一步扩展此设计时功能来创建以下对象:自定义工具箱项,类型特定的值编辑器或类型转换器,其中类型特定的值编辑器用于编辑和以图形方式表示所支持的类型的值;类型转换器用于在特定的类型之间转换值。此命名空间提供了开发设计时用户界面扩展的基本框架。
▲System.Drawing.Drawing2D
提供高级的二维和向量图形功能。此命名空间包括渐变画笔、Matrix 类(用于定义几何转换)和 GraphicsPath 类。
▲System.Drawing.Imaging
提供高级的 GDI 图像处理功能。基本图形功能由 ▲System.Drawing 命名空间提供。
▲System.Drawing.Printing
提供与打印相关的服务。通常情况下,您可以创建 PrintDocument 类的实例,设置描述打印内容的属性,然后调用 Print 方法实际打印文档。
▲System.Drawing.Text
提供高级的 GDI 版式功能。基本图形功能由 ▲System.Drawing 命名空间提供。此命名空间中的类使用户可以创建和使用字体集合。
▲System.EnterpriseServices
为企业级应用程序提供重要的基础结构。COM 为企业级环境中部署的组件编程模型提供服务结构。此命名空间为 .NET Framework 对象提供了对 COM 服务的访问,从而使 .NET Framework 对象更适用于企业级应用程序。
▲System.EnterpriseServices.CompensatingResourceManager
提供使您可以在托管代码中使用补偿资源管理器 (CRM) 的类。CRM 是由 COM 提供的一项服务,它使您可以在 Microsoft 分布式事务处理协调器 (DTC) 事务中包括非事务性对象。虽然 CRM 不提供完整资源管理器的功能,但它们却通过恢复日志提供事务性原子性(全有或全无行为)和持久性。
▲System.EnterpriseServices.Internal
提供 COM 服务的基础结构支持。此命名空间中的类和接口专门用于支持从非托管 COM 类调入 ▲System.EnterpriseServices。
▲System.Globalization
包含定义区域性相关信息的类,这些信息包括语言、国家/地区、正在使用的日历、日期的格式模式、货币、数字以及字符串的排序顺序。这些类对于编写全球化(国际化)应用程序很有用。
▲System.IO
包含允许对数据流和文件进行同步和异步读写的类型。
▲System.IO.IsolatedStorage
包含允许创建和使用独立存储区的类型。通过使用这些存储区,可以读写入受信任程度较小的代码无法访问的数据,并且可以防止公开可保存在文件系统中其他位置的敏感信息。数据存储在独立于当前用户和代码所在的程序集的数据舱中。
▲System.Management
提供对一组丰富的管理信息和管理事件(它们是关于符合 Windows Management Instrumentation (WMI) 基础结构的系统、设备和应用程序的)的访问。
▲System.Management.Instrumentation
提供在规范应用程序管理并通过 WMI 向潜在使用者公开管理信息和事件时必需的类。这样,Microsoft Application Center 或 Microsoft Operations Manager 等使用者就可以轻松地管理您的应用程序,而管理员脚本或其他应用程序(托管应用程序和非托管应用程序)也可以监视和配置您的应用程序。
▲System.Messaging
提供使您可以连接、监视和管理网络上的消息队列以及发送、接收或查看消息的类。
▲System.Net
为当前网络采用的多种协议提供简单的编程接口。WebRequest 和 WebResponse 类构成了所谓的可插接式协议的基础,该协议是一种网络服务的实现,它使您可以开发使用 Internet 资源的应用程序,而不必考虑各个协议的具体细节。
▲System.Net.Sockets
为需要严格控制网络访问的开发人员提供 Windows 套接字 (Winsock) 接口的托管实现。
▲System.Reflection
包含提供已加载类型、方法和字段的托管视图的类和接口,并具有动态创建和调用类型的能力。
▲System.Reflection.Emit
包含允许编译器或工具发出元数据和 Microsoft 中间语言 (MSIL) 并在磁盘上生成 PE 文件(可选)的类。这些类的主要客户端是脚本引擎和编译器。
▲System.Resources
提供允许开发人员创建、存储和管理应用程序中使用的各种区域性特定资源的类和接口。
▲System.Runtime.CompilerServices
为使用托管代码的编译器编写器提供功能,以在影响公共语言运行库的运行时行为的元数据中指定属性。此命名空间中的类只用于编译器编写器。
▲System.Runtime.InteropServices
提供各种支持 COM Interop 和平台调用服务的成员。如果对这些服务不熟悉,请参见与非托管代码交互操作。
▲System.Runtime.InteropServices.CustomMarshalers
支持 .NET 基础结构,不在代码中直接使用。
▲System.Runtime.InteropServices.Expando
包含 IExpando 接口,此接口允许通过添加或移除对象的成员来修改对象。
▲System.Runtime.Remoting
提供允许开发人员创建和配置分布式应用程序的类和接口。
▲System.Runtime.Remoting.Activation
提供支持服务器和客户端远程对象激活的类和对象。
▲System.Runtime.Remoting.Channels
包含支持和处理信道和信道接收器的类,这些信道和信道接收器在客户端对远程对象调用方法时用作传输媒介。
▲System.Runtime.Remoting.Channels.Http
包含使用 HTTP 协议与远程位置之间相互传输消息和对象的信道。默认情况下,HTTP 信道以 SOAP 格式对对象和方法调用进行编码以便传输,但在信道的配置属性中也可以指定其他编码和解码格式化程序接收器。
▲System.Runtime.Remoting.Channels.Tcp
包含使用 TCP 协议与远程位置之间相互传输消息和对象的信道。默认情况下,TCP 信道以二进制格式对对象和方法调用进行编码以便传输,但在信道的配置属性中也可以指定其他编码和解码格式化程序接收器。
▲System.Runtime.Remoting.Contexts
包含定义所有对象所驻留的上下文的对象。上下文是一个有序的属性序列,用于定义其中的对象所处的环境。上下文是在对象的激活过程中创建的,这些对象被配置为要求某些自动服务,如同步、事务、实时 (JIT) 激活、安全性等。多个对象可以存留在一个上下文内。
▲System.Runtime.Remoting.Lifetime
包含管理远程对象生存期的类。传统上,分布式垃圾回收功能使用引用计数和 Ping 来控制对象的生存期。这种机制在每一项服务只有较少的客户端时可以正常工作,但是当每一项服务有几千个客户端时就不能正常工作了。远程处理生存期服务将每一项服务与一个租约关联,当租约到期时,就会删除该服务。生存期服务可以起到传统的分布式垃圾回收器的作用,并且当每一项服务的客户端数量增加时也能很好地调整。
▲System.Runtime.Remoting.Messaging
包含用于创建和远程处理消息的类。远程处理基础结构使用消息与远程对象进行通信。消息用于传输远程方法调用、激活远程对象和交流信息。消息对象携带一组命名属性,其中包括操作标识符、代表信息和参数。
▲System.Runtime.Remoting.Metadata
包含可用于为对象和字段自定义 SOAP 的生成和处理的类和属性。此命名空间中的类可用于指示 SOAPAction、类型输出、XML 元素名和 XML 命名空间 URI 方法。
▲System.Runtime.Remoting.Metadata.W3cXsd2001
包含由万维网联合会 (W3C) 在 2001 年定义的 XML 架构定义 (XSD)。W3C 中的“XML Schema Part2: Data types”(XML 架构第二部分:数据类型)规范确定了各种数据类型的格式和行为。此命名空间包含符合 W3C 规范的数据类型的包装类。所有日期和时间类型都符合 ISO 标准规范。
▲System.Runtime.Remoting.MetadataServices
包含由 Soapsuds.exe 命令行工具和用户代码用来在元数据和远程处理基础结构的 XML 架构之间相互转换的类。
▲System.Runtime.Remoting.Proxies
包含控制和提供代理功能的类。代理是作为远程对象映像的本地对象。代理使客户端可以跨远程处理边界访问对象。
▲System.Runtime.Remoting.Services
包含为 .NET Framework 提供功能的服务类。
▲System.Runtime.Serialization
包含可用于序列化和反序列化对象的类。序列化是将对象或对象图转换为线性的字节序列以存储或传输到其他位置的过程。反序列化是接受存储的信息并用这些信息重新创建对象的过程。
▲System.Runtime.Serialization.Formatters
提供由序列化格式化程序使用的通用枚举、接口和类。
▲System.Runtime.Serialization.Formatters.Binary
包含可用于以二进制格式序列化和反序列化对象的 BinaryFormatter 类。
▲System.Runtime.Serialization.Formatters.Soap
包含可用于以 SOAP 格式序列化和反序列化对象的 SoapFormatter 类。
▲System.Security
提供 .NET Framework 安全系统的基础结构,包括权限的基类。
▲System.Security.Cryptography
提供加密服务,包括数据的安全编码和解码,以及其他许多操作,如哈希处理、随机数生成和消息身份验证。
▲System.Security.Cryptography.X509Certificates
包含 Authenticode X.509 v.3 证书的公共语言运行库实现。此证书用唯一明确标识证书持有者的私钥签名。
▲System.Security.Cryptography.XML
包含支持创建和验证 XML 数字签名的类。此命名空间中的类贯彻了万维网联合会 (W3C) 建议“XML-Signature Syntax and Processing”(XML 签名语法和处理),详见 " 。
▲System.Security.Permissions
定义根据策略控制操作和资源访问的类。
▲System.Security.Policy
包含代码组、成员条件和证据。这三种类型的类用于创建由 .NET Framework 安全策略系统应用的规则。证据类是安全策略的输入,成员条件是开关;二者共同创建策略语句并确定授予的权限集。策略级别和代码组是策略层次的结构。代码组是规则的封装并且在策略级别中分层排列。
▲System.Security.Principal
定义表示运行代码的安全上下文的主体对象。
▲System.ServiceProcess
提供使您可以实现、安装和控制 Windows 服务应用程序的类。服务是不需要用户界面长期运行的可执行文件。实现服务的过程包括:从 ServiceBase 类继承,定义在传入启动、停止、暂停和继续命令时处理的特定行为,以及定义当系统关闭时所采取的自定义行为和操作。
▲System.Text
包含表示 ASCII、Unicode、UTF-7 和 UTF-8 字符编码的类;用于在字符块和字节块之间相互转换的抽象基类;以及不需要创建字符串的中间实例就可以操作和格式化字符串对象的帮助器类。
▲System.Text.RegularExpressions
包含提供对 .NET Framework 正则表达式引擎的访问的类。此命名空间提供的正则表达式功能可在 Microsoft .NET Framework 中运行的任何平台或语言上使用。
▲System.Threading
提供支持多线程编程的类和接口。除了用于同步线程活动和数据访问的类(Mutex、Monitor、Interlocked、AutoResetEvent 等)外,此命名空间还包括一个 ThreadPool 类(使您可以使用系统提供的线程池)和一个 Timer 类(对线程池中的线程执行回调方法)。
▲System.Timers
提供允许以指定的间隔引发事件的 Timer 组件。
▲System.web
提供支持浏览器/服务器通信的类和接口。此命名空间包括 HTTPRequest 类(它提供有关当前 HTTP 请求的大量信息),HTTPResponse 类(它管理 HTTP 到客户端的输出)和 HTTPServerUtility 对象(它提供对服务器端实用工具和进程的访问)。▲System.Web 还包括用于 Cookie 操作、文件传输、异常信息和输出缓存控制的类。
▲System.Web.Caching
提供用于在服务器上缓存常用数据的类。其中包括 Cache 类,该类是一个字典,您可以在其中存储任意数据对象,如哈希表和数据集。它还为这些对象提供了失效功能,并为您提供了添加和移除这些对象的方法。您也可以添加依赖于其他文件或缓存项的对象,并在某个对象从 Cache 中被移除时执行回调以通知您的应用程序。
▲System.Web.Configuration
包含用于设置 ASP.NET 配置的类。
▲System.Web.Hosting
提供从 Microsoft Internet 信息服务 (IIS) 的外部托管应用程序承载 ASP.NET 应用程序的功能。
▲System.Web.Mail
包含使您能够使用 CDOSYS 消息组件构造和发送消息的类。邮件消息通过 Microsoft Windows 2000 中内置的 SMTP 邮件服务或任意的 SMTP 服务器发送。此命名空间中的类可从 ASP.NET 或任何托管应用程序中使用。
▲System.Web.Mobile
包含生成 ASP.NET 移动 Web 应用程序所需的核心功能,其中包括身份验证和错误处理。
▲System.Web.Security
包含用于在 Web 服务器应用程序中实现 ASP.NET 安全的类。
▲System.Web.Services
包含使您可以利用 ASP.NET 和 XML Web services 客户端来创建 XML Web services 的类。XML Web services 是一些应用程序,它们提供了在使用标准协议(如 HTTP、XML、XSD、SOAP 和 WSDL)的松耦合环境下进行消息交换的能力。利用 XML Web services,可以在异质环境下的公司内部和公司之间生成模块化应用程序,使它们与各种各样的实现、平台和设备交互操作。这些应用程序基于 SOAP 的 XML 消息的各部分可以是严格定义的(结构化和类型化)或松散定义的(使用任意 XML)。这些消息能够随时间而发展,并且不会破坏协议,这种能力对于作为未来 Web 构造块的 XML Web services 的灵活性和可靠性来说是最根本的。
▲System.Web.Services.Configuration
由一些类组成,这些类配置用 ASP.NET 创建的 XML Web services 的运行方式。
▲System.Web.Services.Description
由一些类组成,这些类使您能够使用 Web 服务描述语言 (WSDL) 公开描述 XML Web services。此命名空间中的每个类对应于 WSDL 规范中的一个特定元素,并且类层次结构对应于有效的 WSDL 文档的 XML 结构。
▲System.Web.Services.Discovery
由一些类组成,这些类允许 XML Web services 客户端通过称为“XML Web services 发现”的进程来定位 Web 服务器上可用的 XML Web services。
▲System.Web.Services.Protocols
由一些类组成,这些类定义用于在通信期间通过网络在 XML Web services 客户端和用 ASP.NET 创建的 XML Web services 之间传输数据的协议。
▲System.Web.SessionState
提供支持在服务器上存储特定于 Web 应用程序中的单个客户端的数据的类和接口。会话状态数据用于向客户端提供与应用程序的持久连接的外观。状态信息可以存储在本地进程内存中,或者,对于网络场配置来说,可以使用 ASP.NET 状态服务或 SQL Server 数据库将状态信息存储在进程外。
▲System.Web.UI
提供使您可以创建以 Web 页上的用户界面形式出现在 Web 应用程序中的控件和页的类和接口。此命名空间包括 Control 类,该类为所有控件(不论是 HTML 控件、Web 控件还是用户控件)提供一组通用功能。它还包括 Page 控件,每当对 Web 应用程序中的页发出请求时,都会自动生成此控件。另外还提供了一些类,这些类提供 Web 窗体服务器控件数据绑定功能、保存给定控件或页的视图状态的能力,以及对可编程控件和文本控件都适用的分析功能。
▲System.Web.UI.Design
包含可用于扩展 Web 窗体设计时支持的类。
▲System.Web.UI.Design.WebControls
包含可用于扩展 Web 服务器控件设计时支持的类。
▲System.Web.UI.HtmlControls
包含使您可以在 Web 窗体页上创建 HTML 服务器控件的类集合。HTML 服务器控件运行在服务器上,并且直接映射到大多数浏览器所支持的标准 HTML 标记。这使您能够以编程方式控制 Web 窗体页上的 HTML 元素。
▲System.Web.UI.MobileControls
包含一组 ASP.NET 服务器控件,这些控件可以针对不同的移动设备智能地呈现您的应用程序。
▲System.Web.UI.MobileControls.Adapters
包含由 ASP.NET 移动控件用来自定义设备和支持扩展设备的核心设备适配器类。
▲System.Web.UI.WebControls
包含使您可以在 Web 页上创建 Web 服务器控件的类。Web 服务器控件运行在服务器上,并且包括按钮和文本框等窗体控件。它们还包括类似于日历的特殊控件。由于 Web 服务器控件运行在服务器上,因此可以以编程方式来控制这些元素。Web 服务器控件比 HTML 服务器控件更抽象。它们的对象模型不一定反映 HTML 语法。
▲System.Windows.Forms
包含用于创建基于 Windows 的应用程序的类,这些应用程序可以充分利用 Microsoft Windows 操作系统中的丰富用户界面功能。
▲System.Windows.Forms.Design
包含支持 Windows 窗体组件的设计时配置和行为的类。这些类包括:提供 Windows 窗体组件(即一组设计时服务)支持的设计器类、用于配置特定属性类型的 UITypeEditor 类,以及用于导入 ActiveX 控件的类。
▲System.Xml
提供基于标准的 XML 处理支持。
▲System.Xml.Schema
包含提供基于标准的 XML 架构定义语言 (XSD) 架构支持的 XML 类。
▲System.Xml.Serialization
包含用于将对象序列化为 XML 格式的文档或流的类。
▲System.Xml.XPath
包含 XPath 分析器和计算引擎。它支持 W3C XML 路径语言 (XPath) 1.0 版建议 (" )。
▲System.Xml.Xsl
提供可扩展样式表转换 (XSLT) 转换支持。它支持 W3C XSL 转换 (XSLT) 1.0 版建议 (" )。
用法
参考资料:MSDN
通常使用的connect,实际上最后一个参数使用的是Qt::AutoConnection类型:
Qt支持6种连接方式,其中3中最主要:
Qt::DirectConnection(直连方式)
当信号发出后,相应的槽函数将立即被调用。emit语句后的代码将在所有槽函数执行完毕后被执行。(信号与槽函数关系类似于函数调用,同步执行)
Qt::QueuedConnection(排队方式)
当信号发出后,排队到信号队列中,需等到接收对象所属线程的事件循环取得控制权时才取得该信号,调用相应的槽函数。emit语句后的代码将在发出信号后立即被执行,无需等待槽函数执行完毕。(此时信号被塞到信号队列里了,信号与槽函数关系类似于消息通信,异步执行)
Qt::AutoConnection(自动方式)
Qt的默认连接方式,如果信号的发出和接收这个信号的对象同属一个线程,那个工作方式与直连方式相同;否则工作方式与排队方式相同。
参见文章:
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流