梳理.net知识,准备考试
最近需要接受考试。梳理一下.net知识。这里根据记忆来写。有可能不准确。看到错误的同仁请指出来。我会一直维护的,尽量将其维护正确。
.net framework的机制
.net framework包括.net CLR, CTS, CLS, CLI, BCL等组成。
CLR - Common Language Runtime, 是.net程序运行时的环境。CLR包括执行引擎(execution engine),自动化内存管理(GC及其工作方式),.net assembly(一种特殊的Portable Executable)的定义, 类加载器(class loader, 严格的说class loader是execution engine的一部分),IL到二进制的编译器等。
CTS - Common Type system 在.net平台上不同高级语言共同使用的标准类型系统。在IL级别是兼容的。
CLS - Common Language Specification 在IL中有很多元素,为保证.net平台的所有高级语言之间有互操作性而准备的一些特性,比如VB.net 不支持大小写区分,所以CLS就有了不区分大小写的特性。所有这些特性都是为了保证各高级语言之间的互操作性。c#语言中绝大部分是支持CLS的。
CLI - Common Language infrastructure 是CLR的一个子集。包括类加载器class loader, IL到二进制的编译器,GC等。
AppDomain - CLR管理的一块内存区域,包括Assembly在内存里的镜像,栈,堆。一个进程可以有多个AppDomain,同一个线程可以访问多个AppDomain。在CLR4.0以上,一个进程的多个AppDomain可以对应不同的CLR版本。
Assembly - 是编译好的.net的可执行文件.exe或者dll。其中包括各种类型的metadata, 方法体的IL代码。
BCL - Business class library .net framework的类库。这些类库实现某一方面的功能。比如数据库访问。
Shared Assembly - 如mscorlib.dll, 这是每个.net Assembly必须引用的一个Assembly,其中有System名称空间里的最基本的东西。Shared Assembly是在多个AppDomain共享的。对于象mscorlib.dll,还可以跨进程共享的。会被映射到不同进程的VAS(虚拟地址空间)中。
Dedicated Assembly - 通常是我们自己写的Assembly,是专用的。存在于某个特定的AppDomain中。
.net Framework的版本,兼容性
官方资料: http://msdn.microsoft.com/en-us/library/bb822049.aspx
.net 内存管理
这块内容很多,我就简单写一点。
值类型就在栈中分配,引用类型在堆中分配。如果一个值类型是一个引用类型的成员,随引用类型一起在堆中分配内存。
装箱 - 将一个值类型放入堆,需要先将其转换成引用类型Object,才能放入堆。
拆箱 - 将一个装箱的值类型从堆中拿出来,在转化成值类型,再赋给变量。
根 - GC收集的时候,判断一个变量是否可以收集,就是通过从根能否找到指向此变量的引用。直接或者间接引用都可以。如果有,那么就是还在用,如果找不到任何从根到此变量的引用,就可以收集此变量的空间。根指的是静态变量,局部变量,CPU寄存器等。
收集 - 用上述从根找下去的方法,确定一些变量是否还是在用的。找到一些不需要再用的变量,就可以标记此变量可以收集了。一次收集最后,需要将内存压缩,那些零散的空的地方就被压缩了。另外在一次搜集之后还存在的变量,将移动到另外一代的内存空间去。
代和代的空间 - .net CLR在一个进程起来时,会建立三代的内存空间,代0,代1, 代2。这些按预先设计好的默认值来设定每一代的空间大小。新的变量分配空间,总是发生在代0的空间里。当一次收集算法完成后,还是存在的变量被从代0的空间移到了代1的空间里。如果垃圾收集发生在代1的空间里,则还是存在的变量就会被移到了代2的空间里。垃圾收集分代0,代1和代2收集。代2收集的话,代1和代0都得跟着执行,顺序是代0,代1,代2。代1收集的话,代0也得收集,顺序是代0,代1。
大对象堆 - .net有大对象堆。用于大的对象的分配和收集。大对象堆不会进行碎片整理。移动大对象的成本比较高,所以没有安排碎片整理。
Finalize方法 - 用来在程序员忘了将对象释放时的一个解决办法。有Finalize方法的对象创建时就会在CLR结束队列中加入一个链接。一旦该对象不再使用,而又没有显示地调用Dispose(),GC就会将结束队列中的该对象的引用移到待结束队列中,然后有一个单独的线程来一个一个地运行待结束队列中对象的Finalize方法来释放资源。可见:http://www.cnblogs.com/mikelij/archive/2009/05/15/1779850.html
Test stand-alone tool VisualStudio
MSTest /testcontainer:testproject1.dll 这样去运行此测试项目dll中所有test。
/test:<testname> 去运行指定的test。
load testing tool VisualStudio
创建Web test, 指定好主机,并都参数化以后,再创建Load test,将Web test和Load test联系起来。
NUnit
写好Testfix方法,TearDown方法,然后再[Test]方法,用NUnit来运行,测试方法都返回正确,都是绿色的就对了。
SpecFlow
Delegate和Event一个是全集,一个是子集。Event能做的事情,通过Delegate也能胜任。Delegate是Observer模式(也叫model-view,publisher-subscriber,source-lister模式)在C#中的实现。
但Event提供了更好的封装和易用性。Event类型的delegate变量外部只能使用+=,-=的操作,外面的世界,既不能进行赋值(=)的操作和直接进行调用mydelegate()。
而delegate可以进行直接的调用和赋值。
实现delegate
实现一个delegate是非常简单的,通过以下3个步骤即可实现一个delegate:
1. 声明一个delegate对象,他应当和你想要传递的方法具有相同的参数和返回值类型。
2. 创建delegate对象,并将你想要传递的函数作为参数传入。
3. 在要实现异步调用的地方,通过上一步创建的对象来调用方法。
Event实现步骤:
就是这么简单,结合delegate的实现,我们能将自定义事件的实现归结为以下几步:
1. 定义delegate对象类型,他有两个参数,第一个参数是事件发送者对象,第二个参数是事件参数类对象。
2. 定义事件参数类,此类应当从system.eventargs类派生。如果事件不带参数,这一步能省略。
3. 定义事件处理方法,他应当和delegate对象具有相同的参数和返回值类型。
4. 用event关键字定义事件对象,他同时也是个delegate对象。
5. 用+=操作符添加事件到事件队列中(-=操作符能够将事件从队列中删除)。
6. 在需要触发事件的地方用调用delegate的方式写事件触发方法。一般来说,此方法应为protected访问限制,既不能以public方式调用,但能被子类继承。名字是oneventname。
7. 在适当的地方调用事件触发方法触发事件。
Exception handle best practise:
http://msdn.microsoft.com/en-us/library/seyhszts(v=vs.110).aspx