随笔分类 - CLR via C#读书笔记
读书笔记
摘要:多线程涉及到很多知识和技巧…1.线程创建线程是有较大的开销的,每个线程都会占用一定的内存Windows为每个线程的用户模式分配1M的内存,分配24K的内科模式栈,虽然线程可能不运行,切换线程也是有代价的,需要切换线程上下文.2. CLR线程池每个CLR拥有一个线程池.线程池维护线程用来执行用户的异步操作请求.创建一个线程并使用结束之后,线程不会立即销毁,而是返回线程池,等待下一次调用,如果长时间没有用才会自己销毁.类似资源池.两个任务可能使用的是一个线程.3. 执行上下文每个线程都关联了一个执行上下文数据,线程执行代码时,有些操作会受到线程的执行上下文的设置的影响.默认情况下,初始线程的执行上
阅读全文
摘要:1. 基础 反序列化的时候,格式化器会通过调用Assembly.Load方法加载程序集,如果在序列化的时候用的是LoadFrom加载一个程序集,很可能会导致两个程序集不匹配,导出错误. 类型需要添加Serialzable属性才能序列化.而且这个属性不能被继承.此标记可用于Class,Struct,enum,delegate.后两个默认是可序列化的,可不加标记. 如果在序列化一个...
阅读全文
摘要:1. 程序集加载1 Assembly.Load() 这个方法通过程序集的长名称(包括程序集名,版本信息,语言文化,公钥标记)来加载程序集的,会加载此程序集引用的其他程序集,一般情况下都应该优先使用 这个方法,他的执行效率比LoadFrom要高很多,而且不会造成重复加载的问题使用这个方法的时候, CLR会应用一定的策略来查找程序集,实际上CLR按如下的顺序来定位程序集: ⑴如果程序集有强名称,在首先在全局程序集缓(GAC)中查找程序集。 ⑵如果程序集的强名称没有正确指定或GAC中找不到,那么通过配置文件中的元素指定的URL来查找 ⑶如果没有指定强名称或是在GAC中找不到,C...
阅读全文
摘要:1. 概念解析 CLR Hosting(CLR 宿主):初始启动.Net Application时,Windows进程的执行和初始化跟传统的Win32程序是一样的,执行的还是非托管代码,只不过由于PE文件中引入了CLR Header,OS进程加载了mscoree.dll,从而启动了CLR,CLR本身不是一个可执行程序,它需要一个进程来装载并启动它,从而接管进程并创建自身的程序运行上下文,这...
阅读全文
摘要:垃圾回收不是在内存满时才进行,而是只要在0代满了就会进行.而第0代没分配256KB就会满一次. 可以使用GCBeep和GCNotification检查内存回收情况. 垃圾回收采用代的概念,而且只有0,1,2三代. 值类型是不被GC进行垃圾回收的,值类型是在栈上, 当某方法返回时, 栈会恢复到该方法调用前的状态, 该方法在栈上分配的值类型的内存自然就释放了, 不必等GC。而引用类...
阅读全文
摘要:1.try catch finally try中包含的代码通长包含需要清理资源的代码,或者从异常中恢复,或者会抛出异常的代码. Catch包含异常恢复的代码 finally包含资源清理的代码.保证会执行的代码 如果内部的一个catch没有捕获到异常,那么会向外层就是调用方法的那一层查找捕获的代码,总是先执行内部所有的finally语句,由内而外,最后执行Catch的语...
阅读全文
摘要:1.委托揭秘定义一个委托,编译器会生成一个继承自System.MulticastDelegate的类,所有的委托都继承自该类.由于委托是类,所以能定义类的地方,都能定义委托.委托内部有一个target字段,指向调用的实例,如果是静态方法,为null;_methodInfo指向调用的方法.invocationList包含所有定义的委托链.在调用委托时,实际调用的是委托实例的Invoke方法.如:delegate a,a(value),实际是a.Invoke(value). a实际是一个类实例.委托的Remove方法只会删除找到的第一个匹配对象,不会删除所有匹配的对象.+=和-=实际调用的是Del
阅读全文
摘要:1. 字符 Char字符是值类型,16位的Unicode编码.Char.GetUnicodeCategory返回字符类型的枚举.2. String是一个引用类型,代表一个不可变的顺序字符集.分配在堆上.C#编译器把String作为一个基元类型,可以直接定义文本常量,=,Environment.NewLine返回由回车和换行符组成的一个字符串,如 : var s = "s" + Environment.NewLine + "";尽量避免使用+操作符连接几个字符串.会分别创建字符串的.String.clone和Tostring返回对同一个对象的引用,静态方法
阅读全文
摘要:1. 泛型优势:源代码保护类型安全更加清晰的代码更佳的性能.(减少装箱和拆箱的操作)2. Wintellect 的Power Collections库C++的标准模板库的部分集合类3.泛型基础结构开放类型和封闭类型一个泛型的所有类型实参传递的都是实际的数据类型,则成为封闭类型.具有泛型类型参数的类型成为开放类型,CLR禁止构造开放类型的实例.类似禁止构造接口实例.如:var t=typeof(Dictionary); var o=CreateInstance(t);这样是不行的.需要制定类型之后在构造.CLR会为类型对象分配静态字段,对于泛型,List和List,有各自的静态字段,是独立的.如
阅读全文
摘要:1.以引用的方式向方法传递参数ref和out达到效果,传递的是参数的地址而不是参数本身.从CLR的角度看,ref和out完全一致.会生成相同的IL代码.元数据几乎完全一致,只有一个bit除外,以区分这两种情况.为值类型使用out和ref,等同于为引用类型使用传值的方式(普通的方式).以引用的方式传递参数,需要参数类型和方法签名的类型完全相同,哪怕是基类也不行2. 数量可变参数 params如果传递的不是null,会有一定的性能损失.因为在底层中会在堆上分配一个数组,最后垃圾回收.IL中方法会被添加ParamArrayAttribute属性.编译器会优先查找没有可变参数的方法,其次才会查找可变参
阅读全文
摘要:1. 值类型的实例构造器struct Point { public int x, y; public Point(int x, int y) { x = x; y = y; } }值类型的构造器只有在使用New显式调用的时候才会执行.如果只是声明而没用使用New调用构造器,字段会是默认值0. struct Point { public int x, y; public Point() { x = 10; y = 11; ...
阅读全文
摘要:字段修饰符Const 常量的值时在编译时确定的,被视为类型的一部分,是静态成员.会导致创建元数据.引用这个常量时会把这个值直接嵌入IL代码中.Static 静态字段,类型的一部分,占用的内存是在类型对象中分配的.类型对象时在该类型第一次被访问到的时候加载的.对于实例字段则是在创建实例时分配的.而且实例字段在初始化静态字段时,在Vs调试中也是无法看到值的.Readonly 只读字段.只能在构造器写入,而且构造器只会被调用一次.编译器和验证机制会确保readonly字段不会再别的方法中写入.但是readonly字段可以通过反射来修改.如果readonly是引用类型,那么不可修改的是引用,但是引用对
阅读全文
摘要:1. 类型的各种成员System.Runtime.CompilerServices.InternalsVisibleToAttribute(string assemblyName)指定通常仅在当前程序集中可见的类型对指定程序集可见.指定友元程序集.assemblyName包含程序集名字和公司公钥.接口类型必须是Public.如果没有显示声明成员的可访问性,编译器会默认为Private,限制最大的那个.子类重写基类的方法时,只能放宽访问限制,不能缩小.但C#要求两者必须是一样的.是因为CLr承诺派生类总是可以转型为基类,并获取基类方法的访问权,如果在派生类中进行了更严格的限制了,CLR的承诺就无
阅读全文
摘要:1. 溢出 Checked UnCheckedchecked打开时,如果发生溢出会抛出异常,Unchecked则不会排除异常。编译器默认是关闭溢出检查的Unchecked。若要打开溢出检查,使用/Checked+.在VS的项目属性中也可设置开启与否。也可以给一段代码添加这样的标记。如果这段代码中调用了另外一个方法,这个方法是不受这个标记控制的。System.Decimal不是基元类型,Checked和Unchecked标记对其无效,如果发生溢出是肯定会抛出异常的。System。Numberics.BigInteger内部使用UInt32表示任意大的整数,没有上限和下限,永远不会溢出,可能会有内
阅读全文
摘要:1. 所有类型都继承自System.Objectobject的GetType方法是非虚方法,防止基类重写此方法,破坏类型安全性.Var test=new Test(“test”)创建对象时所进行的操作:1. 计算类型及所有基类型中定义的实例字段字节数,以及”类型对象指针”和”同步块索引”.2. 从托管对中分配计算的字节数,所有字节设为零(0).3. 初始化”类型对象指针”和”同步块索引”.4. 调用实例构造函数,传入参数.2. 类型装换if(0 is Employee){ var e=(Employee)o;}var e=o as Employee;if(null!=e){}第一中用法要进..
阅读全文
摘要:1. 强命名程序集由文件名(不记扩展名),版本号,语言文化标示,公钥组成.如:“MyTypes,Version=1.0.8123.0,Culture=netural,PublicKeyToken=b77a5ac55…”System.Reflection.AssemblyName辅助类,可获取和设置有关程序集的这些信息.2. SN.exe StrongName实用程序,用来生成公钥.SN –K MyCompay.snk 生成包含公钥和私钥的SNK文件.SN –p MyCompany.snk MyCompany.PublicKey 生成只包含公钥的文件SN –tp MyCompany.Public
阅读全文
摘要:将类型生成到模块中 1. csc.exe /out:Program.exe /t:exe /r:MSCorLib.dll Program.cs/out:Program.exe /t:exe 是编译器的默认设置/t是/target的意思,指定生成程序的类型./t:exe生成的是CUI控制台应用程序,/t:winexe生成GUI应用程序,/t:library生成DLL文件,/t:module生成一个不包含清单元数据的PE文件,是一个DLL PE文件./r是/reference,告诉编译器在哪些DLL文件中查找外部资源 2. ILDasm.exe IL 反汇编器 ILAsm.exe汇编器 AL.ex
阅读全文
摘要:编译器将源代码编译为托管模块.托管木块包含:PE32或PE32+头CLR头元数据IL(中间语言)代码PE32头的文件可在32或64位的电脑上运行,PE32+的只能在64上运行.Window64位版本提供了一个WoW64的技术,允许32位的程序运行.CLRVer.exe能够列出一台电脑上安装的所有的CLR版本.-all命令可以查看正在运行的进程是使用的CLR版本号./optimize /debug决定代码的IL优化和本地代码的优化质量.NGen.exe可以在一个应用程序安装到用户的计算机时,将IL代码编译为本地代码.这样,CLR的JIT编译器不需要在运行的时候编译IL代码,有助于提示程序性能,但
阅读全文
浙公网安备 33010602011771号