<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_小城岁月</title><subtitle type="text">我可以记住忧伤的回忆，却依然快乐的活着。</subtitle><id>http://feed.cnblogs.com/blog/u/90810/rss</id><updated>2012-02-07T06:17:36Z</updated><author><name>小城岁月</name><uri>http://www.cnblogs.com/mecity/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/mecity/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/90810/rss"/><entry><id>http://www.cnblogs.com/mecity/archive/2012/01/17/WCF.html</id><title type="text">WCF X.509证书创建与IIS宿主设置</title><summary type="text">首先说明，仅仅使用证书只解决了数据明文安全问题的，但请求是否合法，还要通过其它手段，如：双向证书验证 或者 证书+用户验证的方案VS控制台下创建证书示意：1，默认创建证书 makecert -n "CN=www.ecepdi.com" Wcf_EdocFileService.cer (-n搬发给)2, 创建自签名搬发者证书 makecert -n "CN=www.ecepdi.com" -r Wcf_EdocFileService.cer (-r代表自签署)3,创建带私钥部分.pvk的证书 makecert -n "CN=www.ecepdi.</summary><published>2012-01-17T03:48:00Z</published><updated>2012-01-17T03:48:00Z</updated><author><name>小城岁月</name><uri>http://www.cnblogs.com/mecity/</uri></author><link rel="alternate" href="http://www.cnblogs.com/mecity/archive/2012/01/17/WCF.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/mecity/archive/2012/01/17/WCF.html"/><content type="html">&lt;p&gt;首先说明，仅仅使用证书只解决了数据明文安全问题的，但请求是否合法，还要通过其它手段，如：双向证书验证 或者 证书+用户验证的方案&lt;/p&gt;&lt;p&gt;&lt;strong&gt;VS控制台下创建证书示意：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;1，默认创建证书 makecert -n "CN=www.ecepdi.com"&amp;nbsp; Wcf_EdocFileService.cer&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (-n搬发给)&lt;/p&gt;&lt;p&gt;2, 创建自签名搬发者证书 makecert -n "CN=www.ecepdi.com"&amp;nbsp; -r Wcf_EdocFileService.cer&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (-r代表自签署)&lt;/p&gt;&lt;p&gt;3,创建带私钥部分.pvk的证书 makecert -n "CN=www.ecepdi.com"&amp;nbsp; -r -sv Wcf_EdocFileService.pvk Wcf_EdocFileService.cer&lt;/p&gt;&lt;p&gt;4,创建指定位置证书 makecert -r -pe -n "CN=www.ecepdi.com"&amp;nbsp; -sr LocalMachine -ss My -sky exchange&amp;nbsp;&amp;nbsp;&amp;nbsp; (-sr 位置 -n 存储位置)&lt;/p&gt;&lt;p&gt;参数明细参与&lt;/p&gt;&lt;p&gt;MSDN &lt;a href="http://msdn.microsoft.com/zh-cn/bfsktky3(vs.80).aspx"&gt;http://msdn.microsoft.com/zh-cn/bfsktky3(vs.80).aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;如果是IIS做宿主的话最好采好第4种方式，将证书生成到LocalMachine 下My目录， 因为放到CurrentUser/My 下即使设置了密钥的Newwork Service/IIS_USER权限也没法正常读取密钥 ，&lt;/p&gt;&lt;p&gt;所以建议生成到LocalMachine/My下&amp;nbsp;&amp;nbsp;&amp;nbsp; makecert -r -pe -n "CN=www.ecepdi.com"&amp;nbsp; -sr LocalMachine -ss My -sky exchange&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;完成证书制作后，可以通过mmc添加单元-&amp;gt;证书-&amp;gt;添加本地计算机 找到个人下刚生成的证书。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/131283/2012011814424976.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;你可以将证书复制到其它受信区（个人/受信人/受信任的搬发机构等），只要设置好对应的WCF节点指向这些区，当然设置None就会检索所有区域&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;lt;authentication certificateValidationMode="None"/&amp;gt; 可以访问所有受信区，如果需要设置固定位置，则证书位置与WCF此节点设置要一致&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;设置IIS宿主对密钥访问权限&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;此时WCF IIS宿主仍无法读取到读取密钥 可以借助下面两种方式实现&lt;/p&gt;&lt;p&gt;1，下载FindPrivateKey.exe工具，通过命令查找指定证书&lt;/p&gt;&lt;p&gt;FindPrivateKey My LocalMachine -n "CN=www.ecepdi.com"&amp;nbsp;&amp;nbsp;&amp;nbsp; 或&lt;/p&gt;&lt;p&gt;FindPrivateKey My LocalMachine -t "指纹密钥"&amp;nbsp;&lt;/p&gt;&lt;p&gt;查找到对应的密钥存放位置，然后找到此文件，在文件属性安全添加Network Service/IIS_USERS 用户的读权限&lt;/p&gt;&lt;p&gt;2.下载winhttpcertcfg.exe工具（还要设置IIS_USERS的权限）&lt;/p&gt;&lt;p&gt;WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s "证书名" -a Network Service&amp;nbsp;&lt;/p&gt;&lt;p&gt;设置完成后，IIS宿主不是马上就可以访问密钥，所以不要急，可以iisreset命令重启IIS&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;此时在IIS宿主就可以正常访问WCF服务了 ，平时在VS调试时，大家用的都是VS的服务器，所以不会碰到此类问题，但部署到IIS就发现不能正常访问了。&lt;/p&gt;&lt;p&gt;建议WEB开发时，把项目属性-&amp;gt;WEB-&amp;gt;使用本地IIS WEB服务器，以免碰到VS里调试正常但到IIS就不正常了，就不知道怎么回事了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;使用证书应避免客户端与服务端时间差超过5分钟,当两端时间相差过长,则会证书安全错误.(可能原因加密过期)&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&amp;nbsp;WCF IIS 站点x.509证书Web.config配置&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;服务端:&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('7cbd09cb-fddc-42db-b4df-6e47a0369a93')"&gt;&lt;div id="cnblogs_code_open_7cbd09cb-fddc-42db-b4df-6e47a0369a93" class="cnblogs_code_hide"&gt;&amp;lt;system.serviceModel&amp;gt;&lt;br /&gt;    &amp;lt;bindings&amp;gt;&lt;br /&gt;      &amp;lt;wsHttpBinding&amp;gt;&lt;br /&gt;        &amp;lt;binding name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;wsHttpEndpointBinding&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&lt;br /&gt;          &amp;lt;security&amp;gt;&lt;br /&gt;            &amp;lt;message clientCredentialType=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Certificate&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; /&amp;gt;&lt;br /&gt;          &amp;lt;/security&amp;gt;&lt;br /&gt;        &amp;lt;/binding&amp;gt;&lt;br /&gt;      &amp;lt;/wsHttpBinding&amp;gt;&lt;br /&gt;    &amp;lt;/bindings&amp;gt;&lt;br /&gt;    &amp;lt;services&amp;gt; &lt;br /&gt;      &amp;lt;service name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;DemoService.FileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; behaviorConfiguration=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;DemoService.FileServiceBehavior&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&lt;br /&gt;        &amp;lt;endpoint address=&lt;span style="color: #800000;"&gt;""&lt;/span&gt; binding=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;wsHttpBinding&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; contract=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;DemoService.IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; bindingConfiguration=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;wsHttpEndpointBinding&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&lt;br /&gt;          &amp;lt;identity&amp;gt;&lt;br /&gt;            &amp;lt;dns value=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;localhost&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; /&amp;gt;&lt;br /&gt;          &amp;lt;/identity&amp;gt;&lt;br /&gt;        &amp;lt;/endpoint&amp;gt;&lt;br /&gt;        &amp;lt;endpoint address=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;mex&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; binding=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;mexHttpBinding&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; contract=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;IMetadataExchange&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; /&amp;gt;&lt;br /&gt;      &amp;lt;/service&amp;gt;&lt;br /&gt;    &amp;lt;/services&amp;gt;&lt;br /&gt;    &amp;lt;behaviors&amp;gt;&lt;br /&gt;      &amp;lt;serviceBehaviors&amp;gt; &lt;br /&gt;        &amp;lt;behavior name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;DemoService.FileServiceBehavior&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&lt;br /&gt;          &amp;lt;serviceMetadata httpGetEnabled=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;true&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; /&amp;gt;&lt;br /&gt;          &amp;lt;serviceDebug includeExceptionDetailInFaults=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;false&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; /&amp;gt;&lt;br /&gt;          &amp;lt;serviceCredentials&amp;gt;&lt;br /&gt;            &amp;lt;clientCertificate&amp;gt;&lt;br /&gt;              &amp;lt;authentication certificateValidationMode=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;None&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;/&amp;gt;&lt;br /&gt;            &amp;lt;/clientCertificate&amp;gt;&lt;br /&gt;            &amp;lt;serviceCertificate findValue=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WcfServer&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;                                storeLocation=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;LocalMachine&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;                                storeName=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;My&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;                                x509FindType=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;FindBySubjectName&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; /&amp;gt;&lt;br /&gt;          &amp;lt;/serviceCredentials&amp;gt;&lt;br /&gt;        &amp;lt;/behavior&amp;gt;&lt;br /&gt;      &amp;lt;/serviceBehaviors&amp;gt;&lt;br /&gt;    &amp;lt;/behaviors&amp;gt;&lt;br /&gt;  &amp;lt;/system.serviceModel&amp;gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;客户端：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('b91edace-b555-4f36-8d81-1d41249a5051')"&gt;&lt;div id="cnblogs_code_open_b91edace-b555-4f36-8d81-1d41249a5051" class="cnblogs_code_hide"&gt;&amp;lt;system.serviceModel&amp;gt;&lt;br /&gt;        &amp;lt;bindings&amp;gt;&lt;br /&gt;            &amp;lt;wsHttpBinding&amp;gt;&lt;br /&gt;              &amp;lt;binding name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WSHttpBinding_IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; closeTimeout=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;00:01:00&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;               openTimeout=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;00:01:00&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; receiveTimeout=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;00:10:00&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; sendTimeout=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;00:01:00&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;               bypassProxyOnLocal=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;false&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; transactionFlow=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;false&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; hostNameComparisonMode=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;StrongWildcard&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;               maxBufferPoolSize=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;524288&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; maxReceivedMessageSize=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;1073741824&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;               messageEncoding=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Text&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; textEncoding=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;utf-8&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; useDefaultWebProxy=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;true&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;               allowCookies=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;false&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&lt;br /&gt;                    &amp;lt;readerQuotas maxDepth=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;32&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; maxStringContentLength=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;8192&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; maxArrayLength=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;1073741824&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;                        maxBytesPerRead=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;4096&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; maxNameTableCharCount=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;16384&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; /&amp;gt;&lt;br /&gt;                    &amp;lt;reliableSession ordered=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;true&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; inactivityTimeout=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;00:10:00&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;                        enabled=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;false&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; /&amp;gt;&lt;br /&gt;                    &amp;lt;security mode=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Message&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&lt;br /&gt;                        &amp;lt;transport clientCredentialType=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Windows&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; proxyCredentialType=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;None&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;                            realm=&lt;span style="color: #800000;"&gt;""&lt;/span&gt; /&amp;gt;&lt;br /&gt;                        &amp;lt;message clientCredentialType=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Certificate&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; negotiateServiceCredential=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;true&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;                            algorithmSuite=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Default&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; establishSecurityContext=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;true&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; /&amp;gt;&lt;br /&gt;                    &amp;lt;/security&amp;gt;&lt;br /&gt;                &amp;lt;/binding&amp;gt;&lt;br /&gt;            &amp;lt;/wsHttpBinding&amp;gt;&lt;br /&gt;        &amp;lt;/bindings&amp;gt;&lt;br /&gt;        &amp;lt;client&amp;gt;&lt;br /&gt;            &amp;lt;endpoint address=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://localhost:8066/DemoService/FileService.svc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;                binding=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;wsHttpBinding&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; bindingConfiguration=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WSHttpBinding_IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;                contract=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Edoc.IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WSHttpBinding_IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;                 behaviorConfiguration=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WSHttpBinding_IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;      &amp;gt;&lt;br /&gt;                &amp;lt;identity&amp;gt;&lt;br /&gt;                    &amp;lt;dns value=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WcfServer&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; /&amp;gt;&lt;br /&gt;                &amp;lt;/identity&amp;gt;&lt;br /&gt;            &amp;lt;/endpoint&amp;gt;&lt;br /&gt;        &amp;lt;/client&amp;gt;&lt;br /&gt;       &amp;lt;behaviors&amp;gt;&lt;br /&gt;        &amp;lt;endpointBehaviors&amp;gt;&lt;br /&gt;          &amp;lt;behavior name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WSHttpBinding_IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&lt;br /&gt;            &amp;lt;clientCredentials&amp;gt;&lt;br /&gt;              &amp;lt;clientCertificate findValue=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WcfServer&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; x509FindType=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;FindBySubjectName&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; storeLocation=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;LocalMachine&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; storeName=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;My&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;/&amp;gt;&lt;br /&gt;              &amp;lt;serviceCertificate&amp;gt;&lt;br /&gt;                &amp;lt;authentication certificateValidationMode=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;None&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;/&amp;gt;&lt;br /&gt;              &amp;lt;/serviceCertificate&amp;gt;&lt;br /&gt;            &amp;lt;/clientCredentials&amp;gt;&lt;br /&gt;          &amp;lt;/behavior&amp;gt;&lt;br /&gt;        &amp;lt;/endpointBehaviors&amp;gt;&lt;br /&gt;      &amp;lt;/behaviors&amp;gt;&lt;br /&gt;    &amp;lt;/system.serviceModel&amp;gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;在测试过程中，客户端配置&amp;nbsp;&amp;lt;identity&amp;gt;&amp;nbsp;&amp;lt;dns value="WcfServer" /&amp;gt;&amp;lt;/identity&amp;gt; 会被要求设置指向服务端的证书名，所以DNS这个位置不是IP地址而服务端的证书名。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;WCF IIS站点 双向证书&amp;nbsp;配置&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;服务端:&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('39aeb58f-970c-424d-9263-4cdab235001c')"&gt;&lt;div id="cnblogs_code_open_39aeb58f-970c-424d-9263-4cdab235001c" class="cnblogs_code_hide"&gt;&amp;lt;system.serviceModel&amp;gt;&lt;br /&gt;        &amp;lt;services&amp;gt;&lt;br /&gt;   &amp;lt;service behaviorConfiguration=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;DocumentFileService.FileServiceBehavior&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;    name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;DocumentFileService.FileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;endpoint address=&lt;span style="color: #800000;"&gt;""&lt;/span&gt; binding=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;wsHttpBinding&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; contract=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;DocumentFileService.IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; bindingConfiguration=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;DocumentFileService.IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&lt;br /&gt;     &amp;lt;identity&amp;gt;&lt;br /&gt;      &amp;lt;dns value=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;localhost&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; /&amp;gt;&lt;br /&gt;     &amp;lt;/identity&amp;gt;&lt;br /&gt;    &amp;lt;/endpoint&amp;gt;&lt;br /&gt;    &amp;lt;endpoint address=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;mex&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; binding=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;mexHttpBinding&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; contract=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;IMetadataExchange&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; /&amp;gt;&lt;br /&gt;   &amp;lt;/service&amp;gt; &lt;br /&gt;  &amp;lt;/services&amp;gt;&lt;br /&gt;    &amp;lt;behaviors&amp;gt;&lt;br /&gt;   &amp;lt;serviceBehaviors&amp;gt;&lt;br /&gt;    &amp;lt;behavior name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;DocumentFileService.FileServiceBehavior&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&lt;br /&gt;     &amp;lt;serviceMetadata httpGetEnabled=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;true&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; /&amp;gt;&lt;br /&gt;     &amp;lt;serviceDebug includeExceptionDetailInFaults=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;false&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; /&amp;gt;&lt;br /&gt;     &amp;lt;serviceThrottling maxConcurrentCalls=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;1000&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; maxConcurrentSessions=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;1000&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; maxConcurrentInstances =&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;1000&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;/&amp;gt; &amp;lt;!-- 并发控制,最大连接数--&amp;gt;    &lt;br /&gt;      &amp;lt;serviceCredentials&amp;gt;&lt;br /&gt;        &amp;lt;clientCertificate&amp;gt;&lt;br /&gt;          &amp;lt;authentication certificateValidationMode=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Custom&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; customCertificateValidatorType=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;DocumentFileService.ServiceX509CertificateValidator,DocumentFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;/&amp;gt;&lt;br /&gt;        &amp;lt;/clientCertificate&amp;gt;&lt;br /&gt;        &amp;lt;serviceCertificate findValue=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;EdocFileServer&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; storeLocation=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;LocalMachine&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; storeName=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;My&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; x509FindType=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;FindBySubjectName&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;/&amp;gt;&lt;br /&gt;      &amp;lt;/serviceCredentials&amp;gt;&lt;br /&gt;    &amp;lt;/behavior&amp;gt; &lt;br /&gt;   &amp;lt;/serviceBehaviors&amp;gt;&lt;br /&gt;  &amp;lt;/behaviors&amp;gt;&lt;br /&gt;    &amp;lt;bindings&amp;gt;&lt;br /&gt;      &amp;lt;wsHttpBinding&amp;gt;&lt;br /&gt;        &amp;lt;binding name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;DocumentFileService.IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt; &lt;br /&gt;          &amp;lt;security mode=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Message&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&lt;br /&gt;            &amp;lt;message clientCredentialType=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Certificate&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; /&amp;gt;&lt;br /&gt;          &amp;lt;/security&amp;gt;&lt;br /&gt;        &amp;lt;/binding&amp;gt;&lt;br /&gt;      &amp;lt;/wsHttpBinding&amp;gt;&lt;br /&gt;    &amp;lt;/bindings&amp;gt;    &lt;br /&gt;  &amp;lt;/system.serviceModel&amp;gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;客户端:&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('caeabf4e-e603-404c-bf99-fddc676ac07d')"&gt;&lt;div id="cnblogs_code_open_caeabf4e-e603-404c-bf99-fddc676ac07d" class="cnblogs_code_hide"&gt;  &amp;lt;system.serviceModel&amp;gt;&lt;br /&gt;    &amp;lt;bindings&amp;gt;&lt;br /&gt;      &amp;lt;wsHttpBinding&amp;gt;&lt;br /&gt;        &amp;lt;binding name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WSHttpBinding_IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; closeTimeout=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;00:01:00&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; openTimeout=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;00:01:00&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; receiveTimeout=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;00:10:00&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; sendTimeout=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;00:01:00&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; bypassProxyOnLocal=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;false&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; transactionFlow=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;false&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; hostNameComparisonMode=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;StrongWildcard&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; maxBufferPoolSize=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;524288&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; maxReceivedMessageSize=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;1073741824&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; messageEncoding=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Text&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; textEncoding=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;utf-8&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; useDefaultWebProxy=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;true&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; allowCookies=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;false&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&lt;br /&gt;          &amp;lt;readerQuotas maxDepth=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;32&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; maxStringContentLength=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;8192&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; maxArrayLength=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;1073741824&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; maxBytesPerRead=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;4096&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; maxNameTableCharCount=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;16384&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;/&amp;gt;&lt;br /&gt;          &amp;lt;reliableSession ordered=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;true&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; inactivityTimeout=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;00:10:00&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; enabled=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;false&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;/&amp;gt;&lt;br /&gt;          &amp;lt;security mode=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Message&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&lt;br /&gt;            &amp;lt;transport clientCredentialType=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Windows&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; proxyCredentialType=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;None&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; realm=&lt;span style="color: #800000;"&gt;""&lt;/span&gt;/&amp;gt;&lt;br /&gt;            &amp;lt;message clientCredentialType=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Certificate&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; negotiateServiceCredential=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;true&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; algorithmSuite=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Default&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; establishSecurityContext=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;true&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;/&amp;gt;&lt;br /&gt;          &amp;lt;/security&amp;gt;&lt;br /&gt;        &amp;lt;/binding&amp;gt;&lt;br /&gt;      &amp;lt;/wsHttpBinding&amp;gt;&lt;br /&gt;    &amp;lt;/bindings&amp;gt;&lt;br /&gt;    &amp;lt;client&amp;gt;&lt;br /&gt;      &amp;lt;endpoint address=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://ecepdi-da2:8066/FileService.svc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; binding=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;wsHttpBinding&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; bindingConfiguration=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WSHttpBinding_IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; contract=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;EdocFileService.IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WSHttpBinding_IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; behaviorConfiguration=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WSHttpBinding_IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&lt;br /&gt;        &amp;lt;identity&amp;gt;&lt;br /&gt;          &amp;lt;dns value=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;EdocFileServer&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;/&amp;gt;&lt;br /&gt;        &amp;lt;/identity&amp;gt;&lt;br /&gt;      &amp;lt;/endpoint&amp;gt;&lt;br /&gt;    &amp;lt;/client&amp;gt;&lt;br /&gt;    &amp;lt;behaviors&amp;gt;&lt;br /&gt;      &amp;lt;endpointBehaviors&amp;gt;&lt;br /&gt;        &amp;lt;behavior name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;WSHttpBinding_IFileService&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;          &lt;br /&gt;          &amp;lt;clientCredentials&amp;gt;&lt;br /&gt;            &amp;lt;clientCertificate findValue=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;EdocFileClient&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; x509FindType=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;FindBySubjectName&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; storeLocation=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;LocalMachine&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; storeName=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;My&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;/&amp;gt;&lt;br /&gt;            &amp;lt;serviceCertificate&amp;gt;&amp;lt;!--关闭客户端验证服务端证书过程--&amp;gt;&lt;br /&gt;              &amp;lt;authentication certificateValidationMode=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Custom&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; customCertificateValidatorType=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;ECEPDI.Document.WCF_X509.ClientX509CertificateValidator,ECEPDI.Document&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;/&amp;gt;&lt;br /&gt;            &amp;lt;/serviceCertificate&amp;gt;&lt;br /&gt;          &amp;lt;/clientCredentials&amp;gt;&lt;br /&gt;        &amp;lt;/behavior&amp;gt;&lt;br /&gt;      &amp;lt;/endpointBehaviors&amp;gt;&lt;br /&gt;    &amp;lt;/behaviors&amp;gt;&lt;br /&gt;  &amp;lt;/system.serviceModel&amp;gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/mecity/aggbug/2324481.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/mecity/archive/2012/01/17/WCF.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/mecity/archive/2011/11/18/2253899.html</id><title type="text">CLR Via笔记之ThreadPool/Task</title><summary type="text">ThreadPool 是MTA设计，不像STA线程可以支持Com Interop互操作。而Task是ThreadPool的再封装简化，两者都支持异步取消的操作。ThreadPool 通过CancellationTokenSource 取消线程操作private static void CancellingAWorkItem() { CancellationTokenSource cts = new CancellationTokenSource(); ThreadPool.QueueUserWorkItem(o =&gt; Count(cts.Token, 1000))...</summary><published>2011-11-18T05:46:00Z</published><updated>2011-11-18T05:46:00Z</updated><author><name>小城岁月</name><uri>http://www.cnblogs.com/mecity/</uri></author><link rel="alternate" href="http://www.cnblogs.com/mecity/archive/2011/11/18/2253899.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/mecity/archive/2011/11/18/2253899.html"/><content type="html">&lt;p&gt;ThreadPool 是MTA设计，不像STA线程可以支持Com Interop互操作。而Task是ThreadPool的再封装简化，两者都支持异步取消的操作。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ThreadPool 通过CancellationTokenSource 取消线程操作&lt;/strong&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; CancellingAWorkItem() {&lt;br /&gt;        CancellationTokenSource cts = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; CancellationTokenSource(); &lt;br /&gt;        ThreadPool.QueueUserWorkItem(o =&amp;gt; Count(cts.Token, &lt;span style="color: #800080;"&gt;1000&lt;/span&gt;)); &lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;取消线程&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        cts.Cancel();   &lt;br /&gt;       &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Count(CancellationToken token, Int32 countTo) {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (Int32 count = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; count &amp;lt; countTo; count++) {&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;终止线程&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (token.IsCancellationRequested) {              &lt;br /&gt;                &lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;;  &lt;br /&gt;            } &lt;br /&gt;            Thread.Sleep(&lt;span style="color: #800080;"&gt;200&lt;/span&gt;);   &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; For demo, waste some time&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        } &lt;br /&gt;    }&lt;/div&gt;&lt;p&gt;如果在取消时还想通知或调用的其它的方法，可以针对CancellationTokenSource.Token.Register 的注册回调的方法&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; CancellationTokenSource cts = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; CancellationTokenSource();&lt;br /&gt;        cts.Token.Register(() =&amp;gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;已经取消方法执行1&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;));&lt;br /&gt;        cts.Token.Register(() =&amp;gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;已经取消方法执行2&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;));    &lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;执行取消操作&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        cts.Cancel();&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;上面注册的两个Console.WriteLine会被执行&lt;/span&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Task并行任务的处理（Task,Task&amp;lt;&amp;gt; 同Action,Func&amp;lt;&amp;gt;相似）,Task&amp;lt;&amp;gt;的返回结果为委托函数的返回结果&lt;/strong&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; DoTask() {&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;创建任务&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        Task&amp;lt;Int32&amp;gt; t = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task&amp;lt;Int32&amp;gt;(n =&amp;gt; Sum((Int32)n), &lt;span style="color: #800080;"&gt;10000&lt;/span&gt;);         &lt;br /&gt;        t.Start();&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;阻塞等待任务执行完成&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        t.Wait(); &lt;br /&gt;        Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;The sum is: &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + t.Result);   &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; An Int32 value&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Int32 Sum(Int32 n)&lt;br /&gt;    {&lt;br /&gt;        Int32 sum = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (; n &amp;gt; &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; n--) &lt;span style="color: #0000ff;"&gt;checked&lt;/span&gt; { sum += n; }&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; sum;&lt;br /&gt;    }&lt;/div&gt;&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;&amp;nbsp;PS: Task有个IsCompleted属性，也可通过循环判断这个属性来阻塞线程。 但是循环判断比Wait更浪费性能，唤醒线程毕况要比轮询调度CPU要有效率，即使你在轮询判断中增加主线程Sleep也是额外的一种消耗。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;这点和异步编程模型APM很像，比如在异步执行BeginInvoke时，你可以调用EndInvoke阻塞主线程，也可以根据BeginInvoke的IAsyncReult.IsCompleted属性阻塞线程。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Task用一系的属性来定位异步任务的是以何种情况完成的 IsFaulted/IsCompleted/IsCanceled. 因此除了任务属性直接判断一个任务的完成情况，我们还可以通过后续任务观察前一个任务是何种方式完成的，是否有异常情况。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; Task.ContinueWith((task) =&amp;gt; { var _error = task.Exception; }, TaskContinuationOptions.OnlyOnFaulted);&lt;br/&gt; Task.ContinueWith(task =&amp;gt; { var _error = task.Exception; }, TaskContinuationOptions.OnlyOnCanceled);&lt;br/&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Task取消任务的异步操作，同样是利用CancellationTokenSource&lt;/strong&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; CancelTask() {&lt;br /&gt;        CancellationTokenSource cts = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; CancellationTokenSource();&lt;br /&gt;        Task&amp;lt;Int32&amp;gt; t = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task&amp;lt;Int32&amp;gt;(() =&amp;gt; Sum(cts.Token, &lt;span style="color: #800080;"&gt;10000&lt;/span&gt;), cts.Token);&lt;br /&gt;        t.Start();&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;取消异步任务&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        cts.Cancel();&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt; {&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;由于异步任务被取消，任务未正常完成，因此取任务结果会扔出AggregateException异常&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;The sum is: &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + t.Result);    &lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt; (AggregateException ae) {              &lt;br /&gt;            ae.Handle(e =&amp;gt; e &lt;span style="color: #0000ff;"&gt;is&lt;/span&gt; OperationCanceledException);             &lt;br /&gt;            Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Sum was canceled&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Int32 Sum(CancellationToken ct, Int32 n)&lt;br /&gt;    {&lt;br /&gt;        Int32 sum = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (; n &amp;gt; &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; n--)&lt;br /&gt;        { &lt;br /&gt;            ct.ThrowIfCancellationRequested();&lt;br /&gt;            &lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;checked&lt;/span&gt; { sum += n; }&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; sum;&lt;br /&gt;    }&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Task任务结束/中断/异常时等，以这个Task任务做为另一个任务开始的参数，可以通过Task.ContinueWith启动另一个任务执行。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;  &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; ContinueWith() {&lt;br /&gt;        &lt;br /&gt;        Task&amp;lt;Int32&amp;gt; t = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task&amp;lt;Int32&amp;gt;(n =&amp;gt; Sum((Int32)n), &lt;span style="color: #800080;"&gt;10000&lt;/span&gt;);      &lt;br /&gt;        t.Start();&lt;br /&gt;        &lt;br /&gt;        Task cwt = t.ContinueWith(task =&amp;gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;The sum is: &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + task.Result));&lt;br /&gt;        cwt.Wait();   &lt;br /&gt;    }&lt;/div&gt;&lt;p&gt;PS：Task.ContinueWith有多个重载，其中第6个重载枚举参数TaskContinuationOptions 可以控制在多种情况下延续任务执行 ，比如在异常/完成/取消/才执行另外的一个任务&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Task并行多个子任务（比如类似多线程下载的情况：不停的阻塞主线程任务，并且跟踪所有子线程完任务成情况），当然我们用线程也可以解决这些问题，但是 Task简化了这些代码，优化了线程资源使用与回收。&lt;/strong&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; ParentChildTaskDemo() {&lt;br /&gt;        Task&amp;lt;Int32[]&amp;gt; parent = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task&amp;lt;Int32[]&amp;gt;(() =&amp;gt; {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; results = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Int32[&lt;span style="color: #800080;"&gt;3&lt;/span&gt;];   &lt;br /&gt; &lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task(() =&amp;gt; results[&lt;span style="color: #800080;"&gt;0&lt;/span&gt;] = Sum(&lt;span style="color: #800080;"&gt;10000&lt;/span&gt;), TaskCreationOptions.AttachedToParent).Start();&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task(() =&amp;gt; results[&lt;span style="color: #800080;"&gt;1&lt;/span&gt;] = Sum(&lt;span style="color: #800080;"&gt;20000&lt;/span&gt;), TaskCreationOptions.AttachedToParent).Start();&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task(() =&amp;gt; results[&lt;span style="color: #800080;"&gt;2&lt;/span&gt;] = Sum(&lt;span style="color: #800080;"&gt;30000&lt;/span&gt;), TaskCreationOptions.AttachedToParent).Start();&lt;br /&gt;           &lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; results;&lt;br /&gt;        });&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;ContinueWith的任务必须等Parent下的所有子任务全部执行完成才会触发&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; cwt = parent.ContinueWith(parentTask =&amp;gt; Array.ForEach(parentTask.Result, Console.WriteLine));&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;开启并行多任务&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        parent.Start();&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;等待所有任务执行完成&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        cwt.Wait(); &lt;br /&gt;    }&lt;/div&gt;&lt;p&gt;枚举TaskCreationOptions，指定了子任务以何种方式创建与执行。当然还可以利用TaskFactory实现上述方式&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; Task&amp;lt;Int32[]&amp;gt; parent = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task&amp;lt;Int32[]&amp;gt;(() =&amp;gt; {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; results = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Int32[&lt;span style="color: #800080;"&gt;3&lt;/span&gt;];   &lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; cts = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; CancellationTokenSource();&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;var tf = new TaskFactory&amp;lt;Int32&amp;gt;(cts.Token, TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;var tf = new TaskFactory&amp;lt;Int32&amp;gt;();&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;var tf = new TaskFactory&amp;lt;Int32&amp;gt;(cts.Token);&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; tf = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; TaskFactory&amp;lt;Int32&amp;gt;(TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously);&lt;br /&gt;             &lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; childTasks = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;[] {&lt;br /&gt;            tf.StartNew(() =&amp;gt; results[&lt;span style="color: #800080;"&gt;0&lt;/span&gt;] = Sum(&lt;span style="color: #800080;"&gt;10000&lt;/span&gt;)),&lt;br /&gt;            tf.StartNew(() =&amp;gt; results[&lt;span style="color: #800080;"&gt;1&lt;/span&gt;] = Sum(&lt;span style="color: #800080;"&gt;20000&lt;/span&gt;)),&lt;br /&gt;            tf.StartNew(() =&amp;gt; results[&lt;span style="color: #800080;"&gt;2&lt;/span&gt;] = Sum(&lt;span style="color: #800080;"&gt;30000&lt;/span&gt;))   &lt;br /&gt;&lt;br /&gt;            &lt;br /&gt;         };&lt;br /&gt;         &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; results;           &lt;br /&gt;        });&lt;/div&gt;&lt;p&gt;当然你还可以变态点这么写&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;  Task parent = Task.Factory.StartNew(&lt;br /&gt;            () =&amp;gt; Task.Factory.StartNew(&lt;br /&gt;                () =&amp;gt; Task.Factory.StartNew(&lt;br /&gt;                    ()=&amp;gt;Task.Factory.StartNew(&lt;br /&gt;                           o=&amp;gt;Console.WriteLine(o.ToString()),&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;测试&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;br /&gt;                        ))));&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Task还支持异步编程模型（APM），&lt;/strong&gt;参照这段代码&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;Task.Factory.FromAsync&amp;lt;WebResponse&amp;gt;(webRequest.BeginGetResponse, webRequest.EndGetResponse, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, TaskCreationOptions.None);&lt;/div&gt;&lt;p&gt;Task.Factory.FromAsync的其中一个重载首个参数为异步模型BeginInvoke方法，第二个参数为EndInvoke方法，第三个参数object为首个方法的参数，第四个参数为任务类型枚举，其返回类型为第二个方法的返回类型。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Task的延续任务及工厂方式支持异步UI操作 &amp;nbsp;&lt;/strong&gt;TaskContinuationOptions.ExecuteSynchronously/&amp;nbsp;TaskScheduler.FromCurrentSynchronizationContext()&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;上面仅是CLR的读书笔记，想了解很多理论知识，可以参考CLR Via这本MVP联袂推荐的书。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;Task相比手动ThreadPool/Thread编码&amp;nbsp;简化了一系列任务的并行与串行执行问题，以及子任务的执行情况的控制回调变得相对容易。下面是很久以前写的一个多线程同步数据的例子，原理就是通过线程任务集合对象的所有属性的Finish情况来阻塞等待执行最后的任务。4.0编程下Task方便了这些操作，但是3.5以下我们仍然只能这样实现。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;    public abstract class MultiThreadWork &lt;br/&gt;    {&lt;br/&gt;&lt;br/&gt;        public void StartThreadWork(DataTable dtQueue, int taskCount, string userId, string userName)&lt;br/&gt;        {&lt;br/&gt;            try&lt;br/&gt;            {&lt;br/&gt;                //初始线程范围条件  计算每个线程应该接收范围大小&lt;br/&gt;                int averageSize = dtQueue.Rows.Count / taskCount;//平均分配&lt;br/&gt;                int lastSize = averageSize + dtQueue.Rows.Count % taskCount;//剩余部分由最后一个线程完成&lt;br/&gt;&lt;br/&gt;                //生成参数线程对象&lt;br/&gt;                List&amp;lt;WorkItem&amp;gt; list = new List&amp;lt;WorkItem&amp;gt;();&lt;br/&gt;                for (int i = 0; i &amp;lt; taskCount; i++)&lt;br/&gt;                {&lt;br/&gt;                    WorkItem item = new WorkItem();&lt;br/&gt;&lt;br/&gt;                    item.DtQueue = dtQueue;&lt;br/&gt;                    item.IsFinish = false;&lt;br/&gt;                    item.UserId = userId;&lt;br/&gt;                    item.UserName = userName;&lt;br/&gt;&lt;br/&gt;                    item.StarIndex = averageSize * i;//每个线程接起始点&lt;br/&gt;                    if (i &amp;lt; taskCount - 1)&lt;br/&gt;                        item.EndIndex = item.StarIndex + averageSize;//每个线程接收结束点                   &lt;br/&gt;                    else&lt;br/&gt;                        item.EndIndex = item.StarIndex + lastSize;  //最后一个结束点&lt;br/&gt;&lt;br/&gt;                    list.Add(item);&lt;br/&gt;                }&lt;br/&gt;&lt;br/&gt;                //开启工作线程&lt;br/&gt;                foreach (WorkItem item in list)&lt;br/&gt;                {&lt;br/&gt;                    ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), item);&lt;br/&gt;                }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;                //阻塞主线程 等待所有子线程结束&lt;br/&gt;                while (true)&lt;br/&gt;                {&lt;br/&gt;                    //bool isAllFinish = true;&lt;br/&gt;&lt;br/&gt;                    if (!list.Exists(o =&amp;gt; o.IsFinish == false))&lt;br/&gt;                        break;&lt;br/&gt;                    else&lt;br/&gt;                        Thread.Sleep(500);&lt;br/&gt;&lt;br/&gt;                }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;                //通知订阅对象&lt;br/&gt;                AllWorkEventArgs args = new AllWorkEventArgs&lt;br/&gt;                {&lt;br/&gt;                    DtQueue = dtQueue,&lt;br/&gt;                    IsError = false&lt;br/&gt;                };&lt;br/&gt;                this.AllFinishNotify(args);&lt;br/&gt;&lt;br/&gt;            }&lt;br/&gt;            catch (Exception ex)&lt;br/&gt;            {&lt;br/&gt;                //通知订阅对象&lt;br/&gt;                AllWorkEventArgs args = new AllWorkEventArgs&lt;br/&gt;                {&lt;br/&gt;                    DtQueue = dtQueue,&lt;br/&gt;                    IsError = true,&lt;br/&gt;                    ErrorInfo = ex.Message&lt;br/&gt;                };&lt;br/&gt;                this.AllErrorNotify(args);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        /// &amp;lt;summary&amp;gt;&lt;br/&gt;        /// 任务工作方式&lt;br/&gt;        /// &amp;lt;/summary&amp;gt;&lt;br/&gt;        /// &amp;lt;param name="state"&amp;gt;&amp;lt;/param&amp;gt;&lt;br/&gt;        public virtual void DoWork(object state)&lt;br/&gt;        {&lt;br/&gt;            WorkItem item = state as WorkItem;&lt;br/&gt;            try&lt;br/&gt;            {&lt;br/&gt;&lt;br/&gt;                //ClientFileService service = new ClientFileService();&lt;br/&gt;                //service.UploadFile(item.QueueList, item.StarIndex, item.EndIndex, item.UserId, item.UserName);&lt;br/&gt;&lt;br/&gt;                //通知订阅对象&lt;br/&gt;                WorkEventArgs args = new WorkEventArgs();&lt;br/&gt;                args.IsError = false;&lt;br/&gt;                args.WorkItem = item;&lt;br/&gt;                this.SubFinishNotity(args);&lt;br/&gt;            }&lt;br/&gt;            catch (Exception ex)&lt;br/&gt;            {&lt;br/&gt;                //通知订阅对象&lt;br/&gt;                WorkEventArgs args = new WorkEventArgs();&lt;br/&gt;                args.IsError = true;&lt;br/&gt;                args.ErrorInfo = ex.Message;&lt;br/&gt;                args.WorkItem = item;&lt;br/&gt;                this.SubErrorNotify(args);&lt;br/&gt;            }&lt;br/&gt;            finally&lt;br/&gt;            {&lt;br/&gt;                //子线程完成标志&lt;br/&gt;                item.IsFinish = true;&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        #region 通知事件&lt;br/&gt;&lt;br/&gt;        /// &amp;lt;summary&amp;gt;&lt;br/&gt;        /// 错误通知&lt;br/&gt;        /// &amp;lt;/summary&amp;gt;&lt;br/&gt;        public event EventHandler&amp;lt;WorkEventArgs&amp;gt; SubError;&lt;br/&gt;        /// &amp;lt;summary&amp;gt;&lt;br/&gt;        /// 全部下载完成通知&lt;br/&gt;        /// &amp;lt;/summary&amp;gt;&lt;br/&gt;        public event EventHandler&amp;lt;AllWorkEventArgs&amp;gt; AllFinished;&lt;br/&gt;        /// &amp;lt;summary&amp;gt;&lt;br/&gt;        /// 子线程完成通知&lt;br/&gt;        /// &amp;lt;/summary&amp;gt;&lt;br/&gt;        public event EventHandler&amp;lt;WorkEventArgs&amp;gt; SubFinished;&lt;br/&gt;&lt;br/&gt;        public event EventHandler&amp;lt;AllWorkEventArgs&amp;gt; AllError;&lt;br/&gt;&lt;br/&gt;        /// &amp;lt;summary&amp;gt;&lt;br/&gt;        /// 全部任务完成触发事件通知方法&lt;br/&gt;        /// &amp;lt;/summary&amp;gt;&lt;br/&gt;        protected void AllFinishNotify(AllWorkEventArgs args)&lt;br/&gt;        {&lt;br/&gt;            if (AllFinished != null)&lt;br/&gt;            {&lt;br/&gt;                AllFinished(this, args);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        protected void AllErrorNotify(AllWorkEventArgs args)&lt;br/&gt;        {&lt;br/&gt;            if (AllError != null)&lt;br/&gt;            {&lt;br/&gt;                AllError(this, args);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        /// &amp;lt;summary&amp;gt;&lt;br/&gt;        /// 子任务线程出错触发事件通知方法&lt;br/&gt;        /// &amp;lt;param name="args"&amp;gt;&amp;lt;/param&amp;gt;&lt;br/&gt;        protected void SubErrorNotify(WorkEventArgs args)&lt;br/&gt;        {&lt;br/&gt;            if (SubError != null)&lt;br/&gt;            {&lt;br/&gt;                SubError(this, args);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        /// &amp;lt;summary&amp;gt;&lt;br/&gt;        /// 子任务线程完成触发事件通知方法&lt;br/&gt;        /// &amp;lt;/summary&amp;gt;&lt;br/&gt;        /// &amp;lt;param name="args"&amp;gt;&amp;lt;/param&amp;gt;&lt;br/&gt;        protected void SubFinishNotity(WorkEventArgs args)&lt;br/&gt;        {&lt;br/&gt;            if (SubFinished != null)&lt;br/&gt;            {&lt;br/&gt;                SubFinished(this, args);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        #endregion&lt;br/&gt;    }&lt;br/&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/mecity/aggbug/2253899.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/mecity/archive/2011/11/18/2253899.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/mecity/archive/2011/11/16/2251010.html</id><title type="text">CLR Via笔记之.NET 4.0 并行Parallel</title><summary type="text">4.0特性中扩展了并行任务处理，其实就是封装了ThreadPool的Task。园子里有很多介绍Parallel的并行计算，其实我更看好并行查询PLINQ。做过复杂SQL拼接报表的人应该深有体会，当复杂的SQL执行时间过长，你怎么做呢？当存储过程优化后的执行时间还是让人无法接受呢？ 之前的解决方案是将复杂的SQL拆分成几段（可能是多张表）分别并行执行，将查询结果加载至内存，利用LINQ处理获取交集数据最终达到目的，当然这个是牺牲内存的方式达到目的，但是如果查询的数据短期不会有太大变化时，这种方式解决查询速度过慢肯定是个较好的方案。而PLINQ在此基础上又进一步扩大了LINQ战果。下面是PLIN.</summary><published>2011-11-16T03:56:00Z</published><updated>2011-11-16T03:56:00Z</updated><author><name>小城岁月</name><uri>http://www.cnblogs.com/mecity/</uri></author><link rel="alternate" href="http://www.cnblogs.com/mecity/archive/2011/11/16/2251010.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/mecity/archive/2011/11/16/2251010.html"/><content type="html">&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;4.0特性中扩展了并行任务处理，其实就是封装了ThreadPool的Task。园子里有很多介绍Parallel的并行计算，其实我更看好并行查询PLINQ。&amp;nbsp;做过复杂SQL拼接报表的人应该深有体会，当复杂的SQL执行时间过长，你怎么做呢？当存储过程优化后的执行时间还是让人无法接受呢？ 之前的解决方案是将复杂的SQL拆分成几段（可能是多张表）分别并行执行，将查询结果加载至内存，利用LINQ处理获取交集数据最终达到目的，当然这个是牺牲内存的方式达到目的，但是如果查询的数据短期不会有太大变化时，这种方式解决查询速度过慢肯定是个较好的方案。而PLINQ在此基础上又进一步扩大了LINQ战果。下面是PLINQ 150W条记录查询测试代码与结果&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Text;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; Microsoft.Practices.Unity;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; ECEPDI.Document.Application.FileModule;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; ECEPDI.Document.Infrastructure.UnitOfWork;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; ECEPDI.Document.Infrastructure.Repositories;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; ECEPDI.Document.Domain.Entities;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt; ScanFileUploadDemo&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;        {&lt;br /&gt;            ScanFileRepository processRepository = Container.Current.Resolve(&lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;(ScanFileRepository)) &lt;span style="color: #0000ff;"&gt;as&lt;/span&gt; ScanFileRepository;&lt;br /&gt;            Stopwatch sw = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Stopwatch();&lt;br /&gt;            sw.Start();&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; query = processRepository.GetFiltered(o =&amp;gt; o.FileName.Contains(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;F201502S-K0518&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;));&lt;br /&gt;            Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;直接查询结果:&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + query.Count().ToString());&lt;br /&gt;            sw.Stop();&lt;br /&gt;            Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;直接查询数据用时：&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + sw.ElapsedMilliseconds / 1000d);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            sw.Reset();&lt;br /&gt;            sw.Start();&lt;br /&gt;            List&amp;lt;ScanFile&amp;gt; list = processRepository.GetAll().ToList();&lt;br /&gt;            sw.Stop();&lt;br /&gt;            Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;加载数据用时：&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + sw.ElapsedMilliseconds / 1000d);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;-------------------------------------------------&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;            sw.Reset();&lt;br /&gt;            sw.Start();&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; result = &lt;span style="color: #0000ff;"&gt;from&lt;/span&gt; u &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; list&lt;br /&gt;                         &lt;span style="color: #0000ff;"&gt;where&lt;/span&gt; u.FileName.Contains(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;F201502S-K0518&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;)&lt;br /&gt;                         &lt;span style="color: #0000ff;"&gt;select&lt;/span&gt; u;&lt;br /&gt;            Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;单行查询结果:&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + result.Count().ToString());&lt;br /&gt;            sw.Stop();&lt;br /&gt;            Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;单行查询用时:&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + sw.ElapsedMilliseconds / 1000d);&lt;br /&gt;            &lt;br /&gt;            Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;-------------------------------------------------&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;            sw.Reset();&lt;br /&gt;            sw.Start();&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; result2 = &lt;span style="color: #0000ff;"&gt;from&lt;/span&gt; u &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; list.AsParallel()&lt;br /&gt;                          &lt;span style="color: #0000ff;"&gt;where&lt;/span&gt; u.FileName.Contains(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;F201502S-K0518&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;)&lt;br /&gt;                          &lt;span style="color: #0000ff;"&gt;select&lt;/span&gt; u;&lt;br /&gt;            Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;并行查询结果:&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + result2.Count().ToString());&lt;br /&gt;            sw.Stop();&lt;br /&gt;            Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;并行查询用时:&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + sw.ElapsedMilliseconds / 1000d);     &lt;br /&gt;&lt;br /&gt;            Console.ReadLine(); &lt;br /&gt;        } &lt;br /&gt;       &lt;br /&gt;    }&lt;br /&gt;}&lt;/div&gt;&lt;p&gt;用时情况：&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/131283/2011111611382771.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;直接查询结果是生成SQL语句到数据库中查询，结果为5.453 而数据库直接执行相同SQL语然却用时7秒&lt;/p&gt;&lt;p&gt;LINQ内存单行查询结果仅为0.31秒 ，但是前提是数据必须加载到内存中。&lt;/p&gt;&lt;p&gt;PLINQ内存并行查询结果为0.114秒 ，优势非常明显。但是PLINQ并行查询结果排列是无序的（打乱了原先的单行查询结果的顺序），由于每个线程完成时间不一致，导致多个线程查询后合并的结果是无序的。&lt;/p&gt;&lt;p&gt;PLINQ提供了对查询结果的再排序AsOrdered ，当然这会损失一点优势。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Parallel.For/Parallel.ForEach 在现有的情况中很难表现中并行的优势，相比Parallel.Invoke的却有很多的表现机会。对于并行查询和并行任务的应用性能效率提高需要要远多于For/Foreach情况。&lt;/p&gt;&lt;p&gt;Parallel.Invoke 同Tasks一样，在并行任务处理中是个好的选择。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;    Test1();&lt;br /&gt;        Test2();&lt;br /&gt;        Test3();&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;3件事同时做肯定要比一件一件来的快嘛&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        Parallel.Invoke(&lt;br /&gt;           () =&amp;gt; Test1(),&lt;br /&gt;           () =&amp;gt; Test2(),&lt;br /&gt;           () =&amp;gt; Test3());&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;Parallel.For/Parallel.Foreach  在普通的遍历中并不能发挥的太多的优势 （以下情况反而不如For/Foreach)&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        Stopwatch sw = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Stopwatch();&lt;br /&gt;        sw.Start();&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (Int32 i = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; i &amp;lt; &lt;span style="color: #800080;"&gt;1000&lt;/span&gt;; i++) DoWork(i);&lt;br /&gt;        sw.Stop();&lt;br /&gt;        Console.WriteLine(sw.ElapsedMilliseconds / 1000d);&lt;br /&gt;         &lt;br /&gt;&lt;br /&gt;        sw.Reset();&lt;br /&gt;        sw.Start();&lt;br /&gt;        Parallel.For(&lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #800080;"&gt;1000&lt;/span&gt;, i =&amp;gt; DoWork(i));&lt;br /&gt;        sw.Stop();&lt;br /&gt;        Console.WriteLine(sw.ElapsedMilliseconds / 1000d);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; collection = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Int32[&lt;span style="color: #800080;"&gt;0&lt;/span&gt;];        &lt;br /&gt;        sw.Reset();&lt;br /&gt;        sw.Start();&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; collection) DoWork(item);&lt;br /&gt;        sw.Stop();&lt;br /&gt;        Console.WriteLine(sw.ElapsedMilliseconds / 1000d);&lt;br /&gt;&lt;br /&gt;        sw.Reset();&lt;br /&gt;        sw.Start();&lt;br /&gt;        Parallel.ForEach(collection, item =&amp;gt; DoWork(item));&lt;br /&gt;        sw.Stop();&lt;br /&gt;        Console.WriteLine(sw.ElapsedMilliseconds / 1000d);&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;PS：复杂的SQL语句以及存储过程报表，在写的时候非常清楚，但是过段时间再回来改的时候连自己也看不懂了-_-|||。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/mecity/aggbug/2251010.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/mecity/archive/2011/11/16/2251010.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/mecity/archive/2011/11/13/2246933.html</id><title type="text">.NET 序列化与反序化</title><summary type="text">序列化与反序化目的是为了解决对象的传递与持久化操作，如在不同的进程，应用程序哉，服务间传递，对象的保存与状态还原. .net 环境下提供的序列化方式至3.5版本，有二进制，SOAP，XML，DataContract，JavaScript等，开源的有如Json.net等。当然也有自己手动反射实现的，比如利用MemberInfo，或者FormatterServices （二进制，SOAP等方式是封装了FormatterServices 的操作）。以上的几中方式处理序列化的对象都有不同的要求，二进制，SOAP，XML方式要求对象必须属性标记可序列化[Serializable]，而DataContra</summary><published>2011-11-12T17:34:00Z</published><updated>2011-11-12T17:34:00Z</updated><author><name>小城岁月</name><uri>http://www.cnblogs.com/mecity/</uri></author><link rel="alternate" href="http://www.cnblogs.com/mecity/archive/2011/11/13/2246933.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/mecity/archive/2011/11/13/2246933.html"/><content type="html">&lt;p&gt;&lt;strong&gt;序列化与反序化目的是为了解决对象的传递与持久化操作，如在不同的进程，应用程序哉，服务间传递，对象的保存与状态还原.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .net 环境下提供的序列化方式至3.5版本，有二进制，SOAP，XML，DataContract，JavaScript等，开源的有如Json.net等。当然也有自己手动反射实现的，比如利用MemberInfo，或者FormatterServices （二进制，SOAP等方式是封装了FormatterServices 的操作）。以上的几中方式处理序列化的对象都有不同的要求，&lt;strong&gt;二进制，SOAP，XML方式要求对象必须属性标记可序列化[Serializable]，而DataContract，JavaScript则虽然没有强制这种要求，但是Serializable，NonSerialized，OnSerializing，OnDeserialized等属性标记仍然在DataContract，JavaScript格化器执行中有效。&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;ps:序列化与反序列化的对象是原对象的副本，并不是引用。封送传值的对象是要求必须可序列化的。&lt;/p&gt;&lt;p&gt;PS:属性标记 Attribute 在编译时是直接构建带构造参数的Attribute的实例写入元数据及IL中。所以在反射获取的都是Attribute的实例。可以通过Type.IsDefined判断是否标记过属性，这种效率最高。当然还可以通过GetCustomAttribute（获取实例并可以操作）/GetCustomAttributeData（只获取反射实例，但不操作）&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在序列化和反序化的过程，可以对序列化过程做一些其它特殊处理操作。看下面示例的注释&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; [Serializable]&lt;br /&gt;   &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Demo {&lt;br /&gt;&lt;br /&gt;      [NonSerialized]&lt;br /&gt;      &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; name;&lt;br /&gt;      &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; Name&lt;br /&gt;      {&lt;br /&gt;         &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; name; }&lt;br /&gt;         &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt; { name = value; }&lt;br /&gt;      }&lt;br /&gt;       &lt;br /&gt;      [OnSerializing]    &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;被序列化时会执行的方式  解决一些特殊的情况处理&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;      &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; OnSerializing(StreamingContext context) { }&lt;br /&gt;      [OnSerialized]    &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;序列化完成后会调用的方法 解决一些特殊的情况处理&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;      &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; OnSerialized(StreamingContext context) { }&lt;br /&gt;&lt;br /&gt;      [OnDeserializing]    &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;被反序列化时会执行的方式  解决一些特殊的情况处理&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;      &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; OnDeserializing(StreamingContext context) { }&lt;br /&gt;      [OnDeserialized]     &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;被反序列化完成后执行的方式  解决一些特殊的情况处理&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;      &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; OnDeserialized(StreamingContext context) { }&lt;br /&gt;   }&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&amp;nbsp;1.微软提供直接实现序列化与反序列化的实现&lt;/strong&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Text;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.IO;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Runtime.Remoting.Messaging;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Runtime.Serialization;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Runtime.Serialization.Formatters;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Runtime.Serialization.Formatters.Binary;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Runtime.Serialization.Formatters.Soap; &lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Xml.Serialization;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Web;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt; EFTool.Test&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;     &lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 序列化与反序列化帮助类（二进制，SOAP,XML，DataContract格式化操作类）&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; SOAP在3.5以后废弃，取而代之尽量使用XmlSerializer,DataContractSerializer.&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 流格式化可以选择多种方式如FileStream,MemoryStream等&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 封送传值的对象要求必须可序列化标记（副本)，而封送引用的对象可以通过继承MarshalbyRefObject(代理)   &lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; SerializationHelper&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#region&lt;/span&gt; 二进制方式 对象必须标记为Serializable&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 以二进制序列化对象(不必知道对象的具体类型)&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="graph"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;对象必须标记为Serializable&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Stream SerializeByBinary(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; graph)&lt;br /&gt;        {&lt;br /&gt;            MemoryStream memoryStream = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; MemoryStream();            &lt;br /&gt;            IRemotingFormatter formatter = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; BinaryFormatter();&lt;br /&gt;            formatter.Serialize(memoryStream, graph);    &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;已完成序列化到流中（ 此处我们借助其它的流格式，比如说FileStream 将序列化数据转至文件中）&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;Byte[] arrGraph = memoryStream.ToArray();    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;将序列化的结果转换为64位字符串  （转成字符串类型后，可以将数据存至数据库中其传至其它地方）&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; memoryStream;&lt;br /&gt;           &lt;br /&gt;        }&lt;br /&gt;      &lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 反序列化以二进制方式&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="graph"对象必须标记为Serializable&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; T DeserializeByBinary&amp;lt;T&amp;gt;(Stream stream)&lt;br /&gt;        {&lt;br /&gt;            stream.Position = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;;&lt;br /&gt;            IRemotingFormatter formatter = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; BinaryFormatter();&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; (T)formatter.Deserialize(stream);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#region&lt;/span&gt; 二进制深度复制克隆 StreamingContextStates.Clone  对象必须标记为Serializable&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 以二进制序列化对象(不必知道对象的具体类型)&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="graph"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Stream DeepCloneSerializeByBinary(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; graph)&lt;br /&gt;        {&lt;br /&gt;            MemoryStream memoryStream = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; MemoryStream();&lt;br /&gt;            IRemotingFormatter formatter = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; BinaryFormatter();&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;深度复制&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            formatter.Context = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; StreamingContext(StreamingContextStates.Clone);&lt;br /&gt;            formatter.Serialize(memoryStream, graph); &lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; memoryStream;&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 反序列化以二进制方式&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="graph"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; T DeepCloneDeserializeByBinary&amp;lt;T&amp;gt;(Stream stream)&lt;br /&gt;        {&lt;br /&gt;            stream.Position = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;;&lt;br /&gt;            IRemotingFormatter formatter = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; BinaryFormatter();&lt;br /&gt;            formatter.Context = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; StreamingContext(StreamingContextStates.Clone);&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; (T)formatter.Deserialize(stream);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#region&lt;/span&gt; SOAP方式（过时） 对象必须标记为Serializable&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 以SOAP序列化对象(不必知道对象的具体类型)&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="graph"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Stream SerializeBySoap(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; graph)&lt;br /&gt;        {&lt;br /&gt;            MemoryStream memoryStream = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; MemoryStream();            &lt;br /&gt;            IRemotingFormatter formatter = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; SoapFormatter();&lt;br /&gt;            formatter.Serialize(memoryStream, graph);     &lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; memoryStream;&lt;br /&gt;           &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt;  反序列化以SOAP方式&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="graph"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; T DeserializeBySoap&amp;lt;T&amp;gt;(Stream stream)&lt;br /&gt;        {&lt;br /&gt;            stream.Position = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;;&lt;br /&gt;            IRemotingFormatter formatter = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; SoapFormatter();&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; (T)formatter.Deserialize(stream);           &lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#region&lt;/span&gt; XML方式 取代SOAP-&amp;gt;不能处理复杂对象 对象必须标记为Serializable&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 以XML序列化（XML序列化的对象中包含集合类属性可能会引发异常，XML序列对集合类属性序列化有特殊要求）       &lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="graph"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Stream SerializeByXml&amp;lt;T&amp;gt;(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; graph)&lt;br /&gt;        {&lt;br /&gt;            MemoryStream memoryStream = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; MemoryStream();            &lt;br /&gt;            XmlSerializer formatter = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; XmlSerializer(&lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;(T));&lt;br /&gt;            formatter.Serialize(memoryStream, graph);&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; memoryStream;            &lt;br /&gt;        } &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 字符串反序列化对象（XML）&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="graph"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; T DeserializeByXml&amp;lt;T&amp;gt;(Stream stream)&lt;br /&gt;        {&lt;br /&gt;            stream.Position = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;;&lt;br /&gt;            XmlSerializer formatter = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; XmlSerializer(&lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;(T));&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; (T)formatter.Deserialize(stream);            &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#region&lt;/span&gt;  DataContractSerialzer方式 对象不必标记为Serializable&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; DataContractSerialzer序列化对象&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="graph"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Stream SerializeByDataContract&amp;lt;T&amp;gt;(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; graph)&lt;br /&gt;        { &lt;br /&gt;            MemoryStream memoryStream = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; MemoryStream();&lt;br /&gt;            DataContractSerializer formatter = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; DataContractSerializer(&lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;(T));&lt;br /&gt;            formatter.WriteObject(memoryStream,graph);             &lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; memoryStream;            &lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt;  DataContractSerialzer反序列化对象&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;typeparam name="T"&amp;gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="graph"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; T DeserializeByDataContract&amp;lt;T&amp;gt;(Stream stream)&lt;br /&gt;        {&lt;br /&gt;            stream.Position = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;;&lt;br /&gt;            DataContractSerializer formatter = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; DataContractSerializer(&lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;(T));&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;  (T)formatter.ReadObject(stream);             &lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;利用FormatterServices反射实现（同MemberInfo类似）&lt;/strong&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; BlogCategory cate = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; BlogCategory();&lt;br /&gt;            cate.CateID = &lt;span style="color: #800080;"&gt;1&lt;/span&gt;;&lt;br /&gt;            cate.CateName = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;llj&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;;&lt;br /&gt;            cate.CreateTime = DateTime.Now;&lt;br /&gt;            cate.SortID = &lt;span style="color: #800080;"&gt;10&lt;/span&gt;;&lt;br /&gt;            cate.BlogArticle.Add(&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; BlogArticle()&lt;br /&gt;            {&lt;br /&gt;                UserID=&lt;span style="color: #800080;"&gt;20&lt;/span&gt;,&lt;br /&gt;                ArticleID = &lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;br /&gt;                BlogCategory_CateID = &lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;br /&gt;                Title = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;love&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;                CreateTime = DateTime.Now&lt;br /&gt;&lt;br /&gt;            }); &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;获取字段成员及对应的值&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            MemberInfo[] members = FormatterServices.GetSerializableMembers(cate.GetType());&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;object&lt;/span&gt;[] membersValues = FormatterServices.GetObjectData(cate, members);&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; i = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; i &amp;lt; members.Length; i++)&lt;br /&gt;            {&lt;br /&gt;               &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;构建序列化的二进制数据或者XML/JSON等，当然自己要处理大量复杂的业务&lt;br /&gt;               &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;members[i].Name&lt;br /&gt;               &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;membersValues[i]               &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            }&lt;br /&gt;            &lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;反序化为对象&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            BlogCategory cate2 = (BlogCategory)FormatterServices.GetUninitializedObject(&lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;(BlogCategory));&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;BlogCategory cate2 = new BlogCategory();&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            FormatterServices.PopulateObjectMembers(cate2, members, membersValues);&lt;/div&gt;&lt;p&gt;&lt;br /&gt;当然这是一种便捷的方式，也可以通过手动反射实现，要手动实现就得考虑性能与复杂类型的处理问题。比如碰到导航类，或者泛型集合，而Nullable&amp;lt;T&amp;gt;这种泛型值类型通常用以处理非空值类型也会被误认为泛型集合。上一节介绍的&lt;a href="http://www.cnblogs.com/mecity/archive/2011/11/12/2246114.html" target="_blank"&gt;CLR几种反射性能的例子&lt;/a&gt;&amp;nbsp;都可以实现同样的目的。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/mecity/aggbug/2246933.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/mecity/archive/2011/11/13/2246933.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/mecity/archive/2011/11/12/2246114.html</id><title type="text">CLR VIA反射性能比较的例子</title><summary type="text">在CLR VIA 的Demo中看到关于反射性能的几个例子，演示了反射操作实例及性能表现。反射的过程其实就是根据要查找的反射信息（字段名，方法名，类名等），在元数据中逐字符匹配的查找字段名，类型名等，然后定位到IL代码编译执行（所以会有大小写区分）。由于元数据是记录了程序集所有类型以及成员的描述信息，所以在其中查找指定的信息是件浪费性能的事情。如何快速匹配到对应的元数据信息，然后定位到IL执行代码去执行，这是本身反射性能提升的直接途径，当然这个过程已经很难优化，但是可以通过缓存管理首次的结果提高效率。类似JIT对IL方法指令的编译，首次编译后保存CLR 元数据相关的结构表中，再下一次执行时直接上</summary><published>2011-11-11T18:15:00Z</published><updated>2011-11-11T18:15:00Z</updated><author><name>小城岁月</name><uri>http://www.cnblogs.com/mecity/</uri></author><link rel="alternate" href="http://www.cnblogs.com/mecity/archive/2011/11/12/2246114.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/mecity/archive/2011/11/12/2246114.html"/><content type="html">&lt;p&gt;在CLR VIA 的Demo中看到关于反射性能的几个例子，演示了反射操作实例及性能表现。反射的过程其实就是根据要查找的反射信息（字段名，方法名，类名等），在元数据中逐字符匹配的查找字段名，类型名等，然后定位到IL代码编译执行（所以会有大小写区分）。由于元数据是记录了程序集所有类型以及成员的描述信息，所以在其中查找指定的信息是件浪费性能的事情。如何快速匹配到对应的元数据信息，然后定位到IL执行代码去执行，这是本身反射性能提升的直接途径，当然这个过程已经很难优化，但是可以通过缓存管理首次的结果提高效率。类似JIT对IL方法指令的编译，首次编译后保存CLR 元数据相关的结构表中，再下一次执行时直接上次编译的CPU指令。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Text;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Reflection;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Dynamic;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt; Demo&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;        {&lt;br /&gt;            Type t = &lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;(SomeType);&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;方法一  InvokeMember&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            Invoker.UseInvokeMemberToBindAndInvokeTheMember(t);&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;方法二  MemberInfo派生类 SetValue-&amp;gt;GetSetValueMethod-&amp;gt;调用SetValueMethod&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            Invoker.BindToMemberThenInvokeTheMember(t);&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;方法三  委托操作 看IL的调用栈要比上个浅，因为直接查找了GetMethod，但没有缓存仍然每次都要查找         &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            Invoker.BindToMemberCreateDelegateToMemberThenInvokeTheMember(t);&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;方法四 Dynamic动态(4.0特性)，dynamic经过语法糖编译为IL时对实现了类似方法三的效果，&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;但是利用了CallSite的委托缓存容器，一次查找重复利用          &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            Invoker.UseDynamicToBindAndInvokeTheMember(t);&lt;br /&gt;&lt;br /&gt;            Console.ReadLine();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 要反射的类型DEMO&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;sealed&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; SomeType&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; Int32 m_someField;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; SomeType(&lt;span style="color: #0000ff;"&gt;ref&lt;/span&gt; Int32 x) { x *= &lt;span style="color: #800080;"&gt;2&lt;/span&gt;; }&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;override&lt;/span&gt; String ToString() { &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; m_someField.ToString(); }&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; Int32 SomeProp&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; m_someField; }&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt; { m_someField = value; }&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;event&lt;/span&gt; EventHandler SomeEvent;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; NoCompilerWarnings()&lt;br /&gt;        {&lt;br /&gt;            SomeEvent.ToString();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Invoker&lt;br /&gt;    { &lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 过滤成员标志&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;const&lt;/span&gt; BindingFlags c_bf = BindingFlags.DeclaredOnly | BindingFlags.Public |&lt;br /&gt;           BindingFlags.NonPublic | BindingFlags.Instance;&lt;br /&gt;       &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 通过类型的InvokeMember实例的反射成员操作 （最差，次次反射对象）&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="t"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; UseInvokeMemberToBindAndInvokeTheMember(Type t)&lt;br /&gt;        {           &lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Construct an instance of the Type&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            Object[] args = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Object[] { &lt;span style="color: #800080;"&gt;12&lt;/span&gt; };  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Constructor arguments        &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            Object obj = t.InvokeMember(&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, c_bf | BindingFlags.CreateInstance, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, args);          &lt;br /&gt;            &lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Read and write to a field&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            t.InvokeMember(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;m_someField&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, c_bf | BindingFlags.SetField, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, obj, &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Object[] { &lt;span style="color: #800080;"&gt;5&lt;/span&gt; });&lt;br /&gt;            Int32 v = (Int32)t.InvokeMember(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;m_someField&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, c_bf | BindingFlags.GetField, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, obj, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;);        &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Call a method&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            String s = (String)t.InvokeMember(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;ToString&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, c_bf | BindingFlags.InvokeMethod, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, obj, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;);&lt;br /&gt;        &lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Read and write a property&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;            {&lt;br /&gt;                t.InvokeMember(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;SomeProp&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, c_bf | BindingFlags.SetProperty, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, obj, &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Object[] { &lt;span style="color: #800080;"&gt;0&lt;/span&gt; });&lt;br /&gt;            }&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt; (TargetInvocationException e)&lt;br /&gt;            {&lt;br /&gt;                &lt;br /&gt;            }&lt;br /&gt;            t.InvokeMember(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;SomeProp&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, c_bf | BindingFlags.SetProperty, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, obj, &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Object[] { &lt;span style="color: #800080;"&gt;2&lt;/span&gt; });&lt;br /&gt;            v = (Int32)t.InvokeMember(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;SomeProp&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, c_bf | BindingFlags.GetProperty, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, obj, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;);&lt;br /&gt;         &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Add and remove a delegate from the event by invoking the event抯 add/remove methods&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            EventHandler eh = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; EventHandler(EventCallback);&lt;br /&gt;            t.InvokeMember(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;add_SomeEvent&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, c_bf | BindingFlags.InvokeMethod, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, obj, &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Object[] { eh });&lt;br /&gt;            t.InvokeMember(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;remove_SomeEvent&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, c_bf | BindingFlags.InvokeMethod, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, obj, &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Object[] { eh });&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 通过获取构造实例，获取成员反射类型设置（反射一次对象，效率高于上个)&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt;  MemberInfo派生类 SetValue-&amp;gt;GetSetValueMethod-&amp;gt;调用SetValueMethod&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="t"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; BindToMemberThenInvokeTheMember(Type t)&lt;br /&gt;        { &lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Construct an instance&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; ConstructorInfo ctor = t.GetConstructor(new Type[] { Type.GetType("System.Int32&amp;amp;") });&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            ConstructorInfo ctor = t.GetConstructor(&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Type[] { &lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;(Int32).MakeByRefType() });&lt;br /&gt;            Object[] args = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Object[] { &lt;span style="color: #800080;"&gt;12&lt;/span&gt; };  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Constructor arguments          &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            Object obj = ctor.Invoke(args);&lt;br /&gt;         &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Read and write to a field&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            FieldInfo fi = obj.GetType().GetField(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;m_someField&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, c_bf);&lt;br /&gt;            fi.SetValue(obj, &lt;span style="color: #800080;"&gt;33&lt;/span&gt;);&lt;br /&gt;           &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Call a method&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            MethodInfo mi = obj.GetType().GetMethod(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;ToString&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, c_bf);&lt;br /&gt;            String s = (String)mi.Invoke(obj, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;);&lt;br /&gt;           &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Read and write a property&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            PropertyInfo pi = obj.GetType().GetProperty(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;SomeProp&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;(Int32));&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;            {&lt;br /&gt;                pi.SetValue(obj, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;);&lt;br /&gt;            }&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt; (TargetInvocationException e)&lt;br /&gt;            {&lt;br /&gt;                &lt;br /&gt;            }&lt;br /&gt;            pi.SetValue(obj, &lt;span style="color: #800080;"&gt;2&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;);           &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Add and remove a delegate from the event&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            EventInfo ei = obj.GetType().GetEvent(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;SomeEvent&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, c_bf);&lt;br /&gt;            EventHandler eh = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; EventHandler(EventCallback); &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; See ei.EventHandlerType&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            ei.AddEventHandler(obj, eh);&lt;br /&gt;            ei.RemoveEventHandler(obj, eh);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 通过委托执行实例成员的IL方法（效率高于上个,比较适合批量处理大量未知对象的序列化)&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="t"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; BindToMemberCreateDelegateToMemberThenInvokeTheMember(Type t)&lt;br /&gt;        {             &lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Construct an instance (You can't create a delegate to a constructor)&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            Object[] args = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Object[] { &lt;span style="color: #800080;"&gt;12&lt;/span&gt; };  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Constructor arguments           &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            Object obj = Activator.CreateInstance(t, args);       &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; NOTE: You can't create a delegate to a field&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Call a method&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            MethodInfo mi = obj.GetType().GetMethod(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;ToString&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, c_bf);&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; toString = (Func&amp;lt;String&amp;gt;)Delegate.CreateDelegate(&lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;(Func&amp;lt;String&amp;gt;), obj, mi);&lt;br /&gt;            String s = toString();          &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Read and write a property&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            PropertyInfo pi = obj.GetType().GetProperty(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;SomeProp&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;(Int32));&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; setSomeProp = (Action&amp;lt;Int32&amp;gt;)Delegate.CreateDelegate(&lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;(Action&amp;lt;Int32&amp;gt;), obj, pi.GetSetMethod());&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;            {&lt;br /&gt;                setSomeProp(&lt;span style="color: #800080;"&gt;0&lt;/span&gt;);&lt;br /&gt;            }&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt; (ArgumentOutOfRangeException)&lt;br /&gt;            {&lt;br /&gt;                &lt;br /&gt;            }&lt;br /&gt;            setSomeProp(&lt;span style="color: #800080;"&gt;2&lt;/span&gt;);&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; getSomeProp = (Func&amp;lt;Int32&amp;gt;)Delegate.CreateDelegate(&lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;(Func&amp;lt;Int32&amp;gt;), obj, pi.GetGetMethod());&lt;br /&gt;          &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Add and remove a delegate from the event&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            EventInfo ei = obj.GetType().GetEvent(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;SomeEvent&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, c_bf);&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; addSomeEvent = (Action&amp;lt;EventHandler&amp;gt;)Delegate.CreateDelegate(&lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;(Action&amp;lt;EventHandler&amp;gt;), obj, ei.GetAddMethod());&lt;br /&gt;            addSomeEvent(EventCallback);&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; removeSomeEvent = (Action&amp;lt;EventHandler&amp;gt;)Delegate.CreateDelegate(&lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;(Action&amp;lt;EventHandler&amp;gt;), obj, ei.GetRemoveMethod());&lt;br /&gt;            removeSomeEvent(EventCallback);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 动态代理方式UseDynamic，但是利用了CallSite的委托缓存容器，性能要高于方法三    &lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="t"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; UseDynamicToBindAndInvokeTheMember(Type t)&lt;br /&gt;        { &lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Construct an instance (You can't create a delegate to a constructor)&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            Object[] args = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Object[] { &lt;span style="color: #800080;"&gt;12&lt;/span&gt; };  &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Constructor arguments          &lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            dynamic obj = Activator.CreateInstance(t, args); &lt;br /&gt;            &lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Read and write a property&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;            {&lt;br /&gt;                obj.SomeProp = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;;&lt;br /&gt;            }&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt; (ArgumentOutOfRangeException ex)&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; ex;&lt;br /&gt;            }&lt;br /&gt;            obj.SomeProp = &lt;span style="color: #800080;"&gt;2&lt;/span&gt;;&lt;br /&gt;            Int32 val = (Int32)obj.SomeProp;            &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Add and remove a delegate from the event&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            obj.SomeEvent += &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; EventHandler(EventCallback);&lt;br /&gt;            obj.SomeEvent -= &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; EventHandler(EventCallback);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Callback method added to the event&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; EventCallback(Object sender, EventArgs e) { }&lt;br /&gt;    }&lt;br /&gt;}&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/mecity/aggbug/2246114.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/mecity/archive/2011/11/12/2246114.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/mecity/archive/2011/11/08/2240526.html</id><title type="text">进程/线程/线程安全/静态类 杂谈</title><summary type="text">进程 是应用程序的一个实例要使用的资源的一个集合，每个进程都被赋予了一个虚拟空间，以确保另一个其它进程无法访问。进程在者创建时需要分配大量的内存并且初始化加载EXE以及大量的DLL资源。线程相当于逻辑CPU用以解决进程长时间占用资源的问题，在创建时被分配大约1M的内存。线程以CPU时间片单位运行，当时间片到期后自动切换到另一个线程执行，从而缓解一个进程或线程长期占用资源的情况。线程切换伴随着上下文资源的切换，所以大量的线程切换也是浪费性能的事情。一个进程拥有一个专用线程，理论上有多少进程最少就有多少线程，当然实际情况上一个进程可能拥有很多线程。我们可以通过任务管理器的添加选项列线程数来查看一个</summary><published>2011-11-07T17:05:00Z</published><updated>2011-11-07T17:05:00Z</updated><author><name>小城岁月</name><uri>http://www.cnblogs.com/mecity/</uri></author><link rel="alternate" href="http://www.cnblogs.com/mecity/archive/2011/11/08/2240526.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/mecity/archive/2011/11/08/2240526.html"/><content type="html">&lt;p&gt;&lt;strong&gt;进程&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp; 是应用程序的一个实例要使用的资源的一个集合，每个进程都被赋予了一个虚拟空间，以确保另一个其它进程无法访问。&lt;/p&gt;&lt;p&gt;进程在者创建时需要分配大量的内存并且初始化加载EXE以及大量的DLL资源。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;线程&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;相当于逻辑CPU用以解决进程长时间占用资源的问题，在创建时被分配大约1M的内存。线程以CPU时间片单位运行，当时间片到期后自动切换到另一个线程执行，从而缓解一个进程或线程长期占用资源的情况。线程切换伴随着上下文资源的切换，所以大量的线程切换也是浪费性能的事情。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;一个进程拥有一个专用线程，理论上有多少进程最少就有多少线程，当然实际情况上一个进程可能拥有很多线程。我们可以通过任务管理器的添加选项列线程数来查看一个进程拥有多少线程。可以看出大部分进程的CPU使用率为零，但是线程却占据着大量内存资源。（一个线程栈要分配1M内存）。&lt;/p&gt;&lt;p&gt;一般进程的主线程会被标记[STAThread]属性指示应用程序的默认线程模型是单线程单元 (STA)。这个属性主要针对与COM Interop互操作，如果在当前操作COM Interop对象的线程未标记STAThread或设置线程STAThread属性，则会出现异常。如果没有使用COM Interop，一般不需要这个Attribute。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;线程安全&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 只有在多个线程争夺共享资源并且进行破坏操作（如：写操作等）的情况才会有线程安全问题，如果多个线程在调用同一个实例的同一方法时并没出现资源争夺与破坏（如：只读），当然不会存在安全问题。但是大多数情况，非静态类的实例方法大都是操作某些属性字段资源，因此不可必免的出现对同一字段的资源的写操作，从而破坏了数据。同理，静态方法如果引用静态字段也会碰到线程安全的问题。判断一个方法是否线程安全，是看该方法是否存在对共享资源的争夺破坏。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;静态类/静态字段/静态方法&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;静态构造函数（类型构造器）以互斥方式只被CLR执行一次，保证静态构造函数只被执行一次。&lt;/p&gt;&lt;p&gt;静态字段是非线程安全的，在多个线程中共享着同一个实例或静态类的静态字段。&lt;/p&gt;&lt;p&gt;静态方法在多个线程中为同一个实例或静态类的副本，所以是安全的。但是一理静态方法引用了静态字段，就不是线程安全了，因此应在静态方法必免使用静态字段，要么以互斥体的方式操作静态。&lt;/p&gt;&lt;p&gt;大多数据库操作类如SQLHelper此类都设计为静态类的，因为静态方法在不引用静态字段的前提下是线程安全的，所以基本上看到SQL 单连接的情况都是使用静态方法，可以防止单连接并发操作。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;静态字段设计&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;定义静态字段时需要考虑线程安全&lt;/p&gt;&lt;p&gt;const常量定义（const在IL编译自动缀加static，所以不需要在static修饰），常量字段需要定义时就必须初始化一个值。&lt;/p&gt;&lt;p&gt;static readonly 只读静态变量 ，有一次构造初始化静态变量的机会。&lt;/p&gt;&lt;p&gt;当然你如果确实需要线程中修改静态变量的时，那就需要设计一个互斥锁或者InterLocked.CompareExchange方式操作。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;静态事件&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;静态事件同非静态事件一样，区别就在于一个需要类实例化才能注册订阅，而另一个则是直接注册订阅。来看一下场景：&lt;/p&gt;&lt;p&gt;1.当A类（非静态事件）一个实例做一件事想同时通知X，Y，Z几个对象时，则我们要保证传递给X，Y，Z的A的实例必须是同一个。也就是说无论通过构造注入或者属性注入或者方法参数传递，都要保证是同一个A的实例，这样才能保证X，Y，Z注册到的是同一个事件。&lt;/p&gt;&lt;p&gt;但是如果A类是静态事件呢，则我们直接在X，Y，Z中直接注册订阅静态事件，并不需要解决同一个实例传递的问题。 想想如果有大量的不同的对象要通知，那如何保证同一个非静态事件的实例在这些对象中传递呢？&lt;/p&gt;&lt;p&gt;2.假如希望A类（非静态事件）的所有实例做的任何事情都通知到X，Y，Z ，那我们应该怎么做呢？ 那肯定是要A所有实例的非静态事件都被X，Y，Z订阅，这样才能保证X，Y，Z接收到所有A实例事件触发的通知，但是想想这有多困难呢，你怎么知道A类会在哪些地方被实例化呢？并且还要在所有实例化的地方都要重复相同订阅的代码，这是否麻烦呢？我们看一下静态事件怎么解决这个问题的&lt;/p&gt;&lt;p&gt;假如A类使用了静态事件，而X，Y，Z则分别订阅了这个静态事件（只要针对静态事件订阅一次）。我们让A类的非静态方法完成时触发这个静态事件，想想会是什么情况？ 不管A有多少实例化的对象，只要这些对象调用了非态方法触发了静态事件，则X，Y，Z都会收到通知。是不是简单多少了，不用担心A所有实例做的事件你不知道了。 这个应用场景很容易让人联想到数据库操作类，你想知道所有SQL操作，完全可以为你的数据库操作类设计一个静态事件的通知以便能在某个地方监控到的所有SQL语句。&lt;/p&gt;&lt;p&gt;以上两种情况可以看出，静态事件很容易的解决了一对多订阅以及多对一或多对多的订阅通知。当然我们也可以利用单例模式或者IOC容器容易的实现非静态事件分散通知的困难，但是要注意到一点静态字段不等同于静态类，单例模式以静态字段的形式保证了唯一实例，却很可能导致了线程的不安全。因为静态变量资源是被多个线程共享，你无法保证你的实例做为静态使用时，其中不会出资源争夺的情况发生。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;lock/using/foreach/前台线程/后台线程&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在多线程使用lock时，lock代码IL会自动编译为try..catch..finally... ，以确保在发生异常时lock可以正常解锁释放资源。相比Moniter.Entry与Monitr.Exit 就要自己解决异常释放锁的操作。&lt;/p&gt;&lt;p&gt;在using使用时也会自动封装try..catch..finally... ，在finally时会调用资源的Dispose释放对象资源. foreach同样也是如此。&lt;/p&gt;&lt;p&gt;开启线程时，要注意设置前台线程还是后台线程，因为线程终结的方式不一样。&lt;/p&gt;&lt;p&gt;前台线程：进程在关闭时，必须等待前台线程执行完成。&lt;/p&gt;&lt;p&gt;后台线程：进程在关闭时，会直接终止后台线程，导致线程任务无法完成。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/mecity/aggbug/2240526.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/mecity/archive/2011/11/08/2240526.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/mecity/archive/2011/10/29/2228579.html</id><title type="text">EF 最近发展小记</title><summary type="text">最近一直学习硬件负载均衡设备和CLR VIA这本书，没太关注EF的发展。最近可能没时间研究，先做个标记目前EF 已发展4.2版本EF 4.2 Release Candidate Available同时官方博客也推出了Code First的辅助工具用于解决EF Code First Fluent API 手动编码的方案EF Power Tools CTP1 Released确实很方便，生成干净的POCO类以及Map映射类 ，但这种是基于数据库表驱动的方式。Fluent API 类似模型驱动。个人不太喜欢Fluent API ，编码工作多，并且不好维护。简介：NLayerApp项目就是Fluent</summary><published>2011-10-29T06:49:00Z</published><updated>2011-10-29T06:49:00Z</updated><author><name>小城岁月</name><uri>http://www.cnblogs.com/mecity/</uri></author><link rel="alternate" href="http://www.cnblogs.com/mecity/archive/2011/10/29/2228579.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/mecity/archive/2011/10/29/2228579.html"/><content type="html">&lt;p&gt;最近一直学习硬件负载均衡设备和CLR VIA这本书，没太关注EF的发展。最近可能没时间研究，先做个标记&lt;/p&gt;&lt;p&gt;目前EF 已发展4.2版本&lt;/p&gt;&lt;p&gt;&lt;a href="http://blogs.msdn.com/b/adonet/archive/2011/09/28/ef-4-2-release-candidate-available.aspx" target="_blank"&gt;&amp;nbsp;EF 4.2 Release Candidate Available&lt;/a&gt;&lt;/p&gt;&lt;p&gt;同时官方博客也推出了Code First的辅助工具用于解决&amp;nbsp;&lt;a class="internal-link view-post" href="http://blogs.msdn.com/b/adonet/archive/2011/09/13/ef-code-first-fluent-api-with-vb-net.aspx"&gt;EF Code First Fluent API &lt;/a&gt;手动编码的方案&lt;/p&gt;&lt;p&gt;&lt;a class="internal-link view-post" href="http://blogs.msdn.com/b/adonet/archive/2011/05/18/ef-power-tools-ctp1-released.aspx"&gt;EF Power Tools CTP1 Released&lt;/a&gt;&lt;/p&gt;&lt;p&gt;确实很方便，生成干净的POCO类以及Map映射类 ，但这种是基于数据库表驱动的方式。Fluent API 类似模型驱动。&lt;/p&gt;&lt;p&gt;个人不太喜欢Fluent API&amp;nbsp; ，编码工作多，并且不好维护。&lt;/p&gt;&lt;p&gt;简介：NLayerApp项目就是Fluent API 方式。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/mecity/aggbug/2228579.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/mecity/archive/2011/10/29/2228579.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/mecity/archive/2011/10/28/2227954.html</id><title type="text">VS IDE 引用.net 项增加其它DLL项方法</title><summary type="text">打开注册表找到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\ 这一项创建自己的DLL文件夹 假如Mongo 将注册值指向 自己的DLL文件夹 。保存之后我们VS IDE引用一下试试果然可以了，只要做一个就可以了，有新的DLL 直接扔到指定的文件夹下，在VS .NET 引用项中就可以找到这些DLL。 小技巧，估计控件商都是这么处理的。</summary><published>2011-10-28T09:03:00Z</published><updated>2011-10-28T09:03:00Z</updated><author><name>小城岁月</name><uri>http://www.cnblogs.com/mecity/</uri></author><link rel="alternate" href="http://www.cnblogs.com/mecity/archive/2011/10/28/2227954.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/mecity/archive/2011/10/28/2227954.html"/><content type="html">&lt;p&gt;&amp;nbsp;打开注册表找到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\ 这一项&lt;/p&gt;&lt;p&gt;&amp;nbsp;创建自己的DLL文件夹 假如Mongo&amp;nbsp;&amp;nbsp;&amp;nbsp; 将注册值指向 自己的DLL文件夹 。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/131283/2011102817011294.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;保存之后我们VS IDE引用一下试试&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/131283/2011102817012725.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;果然可以了，只要做一个就可以了，有新的DLL 直接扔到指定的文件夹下，在VS .NET 引用项中就可以找到这些DLL。 小技巧，估计控件商都是这么处理的。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/mecity/aggbug/2227954.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/mecity/archive/2011/10/28/2227954.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/mecity/archive/2011/10/27/2226214.html</id><title type="text">GC/Windbg/IDisposable/IL/MeteData/JIT 杂谈</title><summary type="text">GC工作原理大家都已经知道，简单的说就是按代回收托管对象。哪些托管对象会被回收，是通过每个程序的Root来识记，被Root标记的引用对象以及递归出所有相同的引用对象都是活对象，而未被标记的则意味着要被回收。何时回收对象？对于每个对象，CLR首先尝试把对象分配在0代中，如果0代已满，那么GC才会开始工作，把0代中的对象转移到1代中；如果1代也满，GC将会把1代中的对象转移到2代中。也就是说，CLR会在适当的时机，才开始进行垃圾回收。但是对于非托管对象的处理就显得无能为力，但是GC仍然有自己的解决方式。如果非托管对象实现了Finalize方法，代表此非托管对象可终结。因此在非托管对象被创建时，这.</summary><published>2011-10-27T05:34:00Z</published><updated>2011-10-27T05:34:00Z</updated><author><name>小城岁月</name><uri>http://www.cnblogs.com/mecity/</uri></author><link rel="alternate" href="http://www.cnblogs.com/mecity/archive/2011/10/27/2226214.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/mecity/archive/2011/10/27/2226214.html"/><content type="html">&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; GC工作原理大家都已经知道，简单的说就是按代回收托管对象。哪些托管对象会被回收，是通过每个程序的&lt;span style="color: #ff0000;"&gt;Root&lt;/span&gt;来识记，被Root标记的引用对象以及递归出所有相同的引用对象都是活对象，而未被标记的则意味着要被回收。何时回收对象？对于每个对象，CLR首先尝试把对象分配在0代中，如果0代已满，那么GC才会开始工作，把0代中的对象转移到1代中；如果1代也满，GC将会把1代中的对象转移到2代中。也就是说，CLR会在适当的时机，才开始进行垃圾回收。但是对于非托管对象的处理就显得无能为力，但是GC仍然有自己的解决方式。如果非托管对象实现了Finalize方法，代表此非托管对象可终结。因此在非托管对象被创建时，这些对象引用会被GC维护到一个特殊的全局队列中，这个队列被称为终结队列即&lt;span style="color: #ff0000;"&gt;FinalizeQueue&lt;span style="color: #000000;"&gt;. FinzlizeQueue标记的这些对象，程序中没有正确回收或者没有调用这些对象的Finalize/Close，亦或者实现析构，GC的&lt;span style="color: #ff0000;"&gt;Finalize&lt;/span&gt;线程也不会去回收这些对象。因此&lt;/span&gt;&lt;span style="color: #000000;"&gt;，根据上面GC的分析，这里就引出了如何得知这些非托管对象没有被正确的释放掉呢？当我们的程序中大量使用了非托管资源时，经常出现内存不可读不可用的问题时，&lt;span style="color: #ff0000;"&gt;windbg&lt;/span&gt;就是一个好的调试工作，至少最简单的情况可以帮助我们分析哪些对象的Dispose没有被调用，这里只是针对.net 简单使用。上面标记红色的字是windbg中会用到的命令。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; windbg怎么用，园子里可以找到很多文章，这里不多介绍了。下面是测试使用的代码&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('51bcb36c-6724-43c6-ab57-acb6b569b1cd')"&gt;&lt;div id="cnblogs_code_open_51bcb36c-6724-43c6-ab57-acb6b569b1cd" class="cnblogs_code_hide"&gt;        &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; i = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; i &amp;lt; &lt;span style="color: #800080;"&gt;3&lt;/span&gt;; i++)&lt;br /&gt;            {&lt;br /&gt;                Thread t1 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Thread(&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ThreadStart(Create));&lt;br /&gt;                t1.Start();&lt;br /&gt;            }  &lt;br /&gt;           &lt;br /&gt;            Console.ReadLine();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Create()&lt;br /&gt;        {&lt;br /&gt;            Mongo mongo = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Mongo(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Server=172.16.0.25:27017;Pooled=true&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;            mongo.Connect();&lt;br /&gt;            IMongoDatabase simple = mongo[&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;simple&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;];&lt;br /&gt;            mongo.Disconnect();&lt;br /&gt;            mongo.Dispose();&lt;br /&gt;        }&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;&lt;span style="color: #000000;"&gt;运行Demo.exe&amp;nbsp; 开启windbg 将demo.exe附加进来&amp;nbsp;&amp;nbsp;&amp;nbsp; 首次使用windbg 调试.net 程序要加载mscorwks.dll&amp;nbsp;&amp;nbsp; 命令&amp;nbsp; .loadby sos mscorwks&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;:&lt;span style="color: #800080;"&gt;006&lt;/span&gt;&amp;gt; !threads&lt;br /&gt;*********************************************************************&lt;br /&gt;* Symbols can not be loaded because symbol path &lt;span style="color: #0000ff;"&gt;is&lt;/span&gt; not initialized. *&lt;br /&gt;*                                                                   *&lt;br /&gt;* The Symbol Path can be &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt; by:                                    *&lt;br /&gt;*   &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; the _NT_SYMBOL_PATH environment variable.                 *&lt;br /&gt;*   &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; the -y &amp;lt;symbol_path&amp;gt; argument when starting the debugger. *&lt;br /&gt;*   &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; .sympath and .sympath+                                    *&lt;br /&gt;*********************************************************************&lt;br /&gt;PDB symbol &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; mscorwks.dll not loaded&lt;br /&gt;ThreadCount: &lt;span style="color: #800080;"&gt;7&lt;/span&gt;&lt;br /&gt;UnstartedThread: &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;br /&gt;BackgroundThread: &lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;br /&gt;PendingThread: &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;br /&gt;DeadThread: &lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;br /&gt;Hosted Runtime: no&lt;br /&gt;                                      PreEmptive   GC Alloc           Lock&lt;br /&gt;       ID OSID ThreadOBJ    State     GC       Context       Domain   Count APT Exception&lt;br /&gt;   &lt;span style="color: #800080;"&gt;0&lt;/span&gt;    &lt;span style="color: #800080;"&gt;1&lt;/span&gt; 12a4 004c99f0      a020 Enabled  01b1c108:01b1c4ac 004c5428     &lt;span style="color: #800080;"&gt;1&lt;/span&gt; MTA&lt;br /&gt;   &lt;span style="color: #800080;"&gt;2&lt;/span&gt;    &lt;span style="color: #800080;"&gt;2&lt;/span&gt;  &lt;span style="color: #800080;"&gt;610&lt;/span&gt; 004d8a18      b220 Enabled  &lt;span style="color: #800080;"&gt;00000000&lt;/span&gt;:&lt;span style="color: #800080;"&gt;00000000&lt;/span&gt; 004c5428     &lt;span style="color: #800080;"&gt;0&lt;/span&gt; MTA (Finalizer)&lt;br /&gt;XXXX    &lt;span style="color: #800080;"&gt;3&lt;/span&gt;    &lt;span style="color: #800080;"&gt;0&lt;/span&gt; 00544d88      &lt;span style="color: #800080;"&gt;9820&lt;/span&gt; Enabled  &lt;span style="color: #800080;"&gt;00000000&lt;/span&gt;:&lt;span style="color: #800080;"&gt;00000000&lt;/span&gt; 004c5428     &lt;span style="color: #800080;"&gt;0&lt;/span&gt; MTA&lt;br /&gt;XXXX    &lt;span style="color: #800080;"&gt;4&lt;/span&gt;    &lt;span style="color: #800080;"&gt;0&lt;/span&gt; &lt;span style="color: #800080;"&gt;00546558&lt;/span&gt;      &lt;span style="color: #800080;"&gt;9820&lt;/span&gt; Enabled  &lt;span style="color: #800080;"&gt;00000000&lt;/span&gt;:&lt;span style="color: #800080;"&gt;00000000&lt;/span&gt; 004c5428     &lt;span style="color: #800080;"&gt;0&lt;/span&gt; Ukn&lt;br /&gt;XXXX    &lt;span style="color: #800080;"&gt;5&lt;/span&gt;    &lt;span style="color: #800080;"&gt;0&lt;/span&gt; 005583b0      &lt;span style="color: #800080;"&gt;9820&lt;/span&gt; Enabled  &lt;span style="color: #800080;"&gt;00000000&lt;/span&gt;:&lt;span style="color: #800080;"&gt;00000000&lt;/span&gt; 004c5428     &lt;span style="color: #800080;"&gt;0&lt;/span&gt; Ukn&lt;br /&gt;   &lt;span style="color: #800080;"&gt;3&lt;/span&gt;    &lt;span style="color: #800080;"&gt;6&lt;/span&gt; 17dc 0055bb30    80a220 Enabled  &lt;span style="color: #800080;"&gt;00000000&lt;/span&gt;:&lt;span style="color: #800080;"&gt;00000000&lt;/span&gt; 004c5428     &lt;span style="color: #800080;"&gt;0&lt;/span&gt; MTA (Threadpool Completion Port)&lt;br /&gt;   &lt;span style="color: #800080;"&gt;5&lt;/span&gt;    &lt;span style="color: #800080;"&gt;7&lt;/span&gt;  e58 0056c2c0   180b220 Enabled  01b6c0a8:01b6dfe8 004c5428     &lt;span style="color: #800080;"&gt;0&lt;/span&gt; MTA (Threadpool Worker)&lt;/div&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;&lt;span style="color: #000000;"&gt;可以看到有7个线程，DeadThread的线程就是我们循环创建的3个线程 .（说明Thread创建的线程不会被马上回收掉）&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;&lt;span style="color: #000000;"&gt;通过FinalizeQueue查看哪些对象未被回收掉&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;:&lt;span style="color: #800080;"&gt;005&lt;/span&gt;&amp;gt; !FinalizeQueue&lt;br /&gt;SyncBlocks to be cleaned up: &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;br /&gt;MTA Interfaces to be released: &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;br /&gt;STA Interfaces to be released: &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;br /&gt;----------------------------------&lt;br /&gt;generation &lt;span style="color: #800080;"&gt;0&lt;/span&gt; has &lt;span style="color: #800080;"&gt;151&lt;/span&gt; finalizable objects (03dd3a80-&amp;gt;03dd3cdc)&lt;br /&gt;generation &lt;span style="color: #800080;"&gt;1&lt;/span&gt; has &lt;span style="color: #800080;"&gt;0&lt;/span&gt; finalizable objects (03dd3a80-&amp;gt;03dd3a80)&lt;br /&gt;generation &lt;span style="color: #800080;"&gt;2&lt;/span&gt; has &lt;span style="color: #800080;"&gt;0&lt;/span&gt; finalizable objects (03dd3a80-&amp;gt;03dd3a80)&lt;br /&gt;Ready &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; finalization &lt;span style="color: #800080;"&gt;0&lt;/span&gt; objects (03dd3cdc-&amp;gt;03dd3cdc)&lt;br /&gt;Statistics:&lt;br /&gt;      MT    Count    TotalSize Class Name&lt;br /&gt;51bb4a04        &lt;span style="color: #800080;"&gt;1&lt;/span&gt;           &lt;span style="color: #800080;"&gt;20&lt;/span&gt; Microsoft.Win32.SafeHandles.SafeFileMappingHandle&lt;br /&gt;51bb49ac        &lt;span style="color: #800080;"&gt;1&lt;/span&gt;           &lt;span style="color: #800080;"&gt;20&lt;/span&gt; Microsoft.Win32.SafeHandles.SafeViewOfFileHandle&lt;br /&gt;5134a69c        &lt;span style="color: #800080;"&gt;1&lt;/span&gt;           &lt;span style="color: #800080;"&gt;20&lt;/span&gt; Microsoft.Win32.SafeHandles.SafeFileMapViewHandle&lt;br /&gt;51b971ac        &lt;span style="color: #800080;"&gt;1&lt;/span&gt;           &lt;span style="color: #800080;"&gt;24&lt;/span&gt; System.Threading.TimerBase&lt;br /&gt;51ba12a4        &lt;span style="color: #800080;"&gt;2&lt;/span&gt;           &lt;span style="color: #800080;"&gt;40&lt;/span&gt; Microsoft.Win32.SafeHandles.SafePEFileHandle&lt;br /&gt;5134a644        &lt;span style="color: #800080;"&gt;2&lt;/span&gt;           &lt;span style="color: #800080;"&gt;40&lt;/span&gt; Microsoft.Win32.SafeHandles.SafeFileMappingHandle&lt;br /&gt;5134a5ec        &lt;span style="color: #800080;"&gt;2&lt;/span&gt;           &lt;span style="color: #800080;"&gt;40&lt;/span&gt; Microsoft.Win32.SafeHandles.SafeLocalMemHandle&lt;br /&gt;00168fd4        &lt;span style="color: #800080;"&gt;3&lt;/span&gt;           &lt;span style="color: #800080;"&gt;60&lt;/span&gt; MongoDB.Connections.Connection&lt;br /&gt;517a9fd4        &lt;span style="color: #800080;"&gt;3&lt;/span&gt;           &lt;span style="color: #800080;"&gt;72&lt;/span&gt; System.Net.Sockets.TcpClient&lt;br /&gt;5133ec98        &lt;span style="color: #800080;"&gt;3&lt;/span&gt;           &lt;span style="color: #800080;"&gt;72&lt;/span&gt; System.Net.SafeCloseSocket&lt;br /&gt;00e00a10        &lt;span style="color: #800080;"&gt;3&lt;/span&gt;           &lt;span style="color: #800080;"&gt;96&lt;/span&gt; MongoDB.Connections.RawConnection&lt;br /&gt;5133e590        &lt;span style="color: #800080;"&gt;5&lt;/span&gt;          &lt;span style="color: #800080;"&gt;100&lt;/span&gt; System.Net.SafeCloseSocket+InnerSafeCloseSocket&lt;br /&gt;51baeab4        &lt;span style="color: #800080;"&gt;6&lt;/span&gt;          &lt;span style="color: #800080;"&gt;120&lt;/span&gt; Microsoft.Win32.SafeHandles.SafeFileHandle&lt;br /&gt;5134a6f4        &lt;span style="color: #800080;"&gt;6&lt;/span&gt;          &lt;span style="color: #800080;"&gt;120&lt;/span&gt; Microsoft.Win32.SafeHandles.SafeProcessHandle&lt;br /&gt;51334fb0        &lt;span style="color: #800080;"&gt;1&lt;/span&gt;          &lt;span style="color: #800080;"&gt;160&lt;/span&gt; System.Diagnostics.Process&lt;br /&gt;51baa298       &lt;span style="color: #800080;"&gt;11&lt;/span&gt;          &lt;span style="color: #800080;"&gt;176&lt;/span&gt; System.WeakReference&lt;br /&gt;51b97b24       &lt;span style="color: #800080;"&gt;10&lt;/span&gt;          &lt;span style="color: #800080;"&gt;200&lt;/span&gt; Microsoft.Win32.SafeHandles.SafeWaitHandle&lt;br /&gt;51bb10bc        &lt;span style="color: #800080;"&gt;4&lt;/span&gt;          &lt;span style="color: #800080;"&gt;224&lt;/span&gt; System.Threading.Thread&lt;br /&gt;5133e420        &lt;span style="color: #800080;"&gt;3&lt;/span&gt;          &lt;span style="color: #800080;"&gt;228&lt;/span&gt; System.Net.Sockets.Socket&lt;br /&gt;51b85070        &lt;span style="color: #800080;"&gt;4&lt;/span&gt;          &lt;span style="color: #800080;"&gt;320&lt;/span&gt; System.IO.FileStream&lt;br /&gt;51bab304       &lt;span style="color: #800080;"&gt;18&lt;/span&gt;          &lt;span style="color: #800080;"&gt;360&lt;/span&gt; Microsoft.Win32.SafeHandles.SafeRegistryHandle&lt;br /&gt;51baa2f0       &lt;span style="color: #800080;"&gt;11&lt;/span&gt;          &lt;span style="color: #800080;"&gt;484&lt;/span&gt; System.Threading.ReaderWriterLock&lt;br /&gt;51b981a8       &lt;span style="color: #800080;"&gt;40&lt;/span&gt;          &lt;span style="color: #800080;"&gt;800&lt;/span&gt; Microsoft.Win32.SafeHandles.SafeTokenHandle&lt;br /&gt;51349f2c       &lt;span style="color: #800080;"&gt;10&lt;/span&gt;         &lt;span style="color: #800080;"&gt;1200&lt;/span&gt; System.Diagnostics.PerformanceCounter&lt;br /&gt;Total &lt;span style="color: #800080;"&gt;151&lt;/span&gt; objects&lt;/div&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;&lt;span style="color: #000000;"&gt;其中mongodb Connection 3条 RawConnection&amp;nbsp; 3条以及&amp;nbsp; Socket 3条&amp;nbsp;是由掉死的3个线程 创建的&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;&lt;span style="color: #000000;"&gt;看一下RawConnection 的情况&amp;nbsp; MT00e00a10&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;:&lt;span style="color: #800080;"&gt;005&lt;/span&gt;&amp;gt; !dumpheap -mt 00e00a10&lt;br /&gt; Address       MT     Size&lt;br /&gt;01b116e8 00e00a10       &lt;span style="color: #800080;"&gt;32&lt;/span&gt;     &lt;br /&gt;01b12db4 00e00a10       &lt;span style="color: #800080;"&gt;32&lt;/span&gt;     &lt;br /&gt;01b1f924 00e00a10       &lt;span style="color: #800080;"&gt;32&lt;/span&gt;     &lt;br /&gt;total &lt;span style="color: #800080;"&gt;3&lt;/span&gt; objects&lt;br /&gt;Statistics:&lt;br /&gt;      MT    Count    TotalSize Class Name&lt;br /&gt;00e00a10        &lt;span style="color: #800080;"&gt;3&lt;/span&gt;           &lt;span style="color: #800080;"&gt;96&lt;/span&gt; MongoDB.Connections.RawConnection&lt;br /&gt;Total &lt;span style="color: #800080;"&gt;3&lt;/span&gt; objects&lt;/div&gt;&lt;p&gt;看看为什么GC没有回收，说明有根在标记这个对象为活动状态 ，我们通过GCRoot 来查看根的情况&amp;nbsp;&amp;nbsp;&amp;nbsp; address&amp;nbsp; 01b116e8&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;:&lt;span style="color: #800080;"&gt;005&lt;/span&gt;&amp;gt; !GCRoot 01b116e8&lt;br /&gt;Note: Roots found on stacks may be &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt; positives. Run &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;!help gcroot&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;br /&gt;more info.&lt;br /&gt;Scan Thread &lt;span style="color: #800080;"&gt;0&lt;/span&gt; OSTHread 15b8&lt;br /&gt;Scan Thread &lt;span style="color: #800080;"&gt;2&lt;/span&gt; OSTHread &lt;span style="color: #800080;"&gt;1340&lt;/span&gt;&lt;br /&gt;Scan Thread &lt;span style="color: #800080;"&gt;3&lt;/span&gt; OSTHread &lt;span style="color: #800080;"&gt;1298&lt;/span&gt;&lt;br /&gt;DOMAIN(003A5428):HANDLE(Pinned):1213ec:Root:02a73250(System.Object[])-&amp;gt;&lt;br /&gt;01b14e1c(System.Collections.Generic.Dictionary`&lt;span style="color: #800080;"&gt;2&lt;/span&gt;[[System.String, mscorlib],[MongoDB.Connections.IConnectionFactory, MongoDB]])-&amp;gt;&lt;br /&gt;01b1f8c0(System.Collections.Generic.Dictionary`&lt;span style="color: #800080;"&gt;2&lt;/span&gt;+Entry[[System.String, mscorlib],[MongoDB.Connections.IConnectionFactory, MongoDB]][])-&amp;gt;&lt;br /&gt;01b1f36c(MongoDB.Connections.PooledConnectionFactory)-&amp;gt;&lt;br /&gt;01b1f39c(System.Collections.Generic.Queue`&lt;span style="color: #800080;"&gt;1&lt;/span&gt;[[MongoDB.Connections.RawConnection, MongoDB]])-&amp;gt;&lt;br /&gt;01b1fed4(System.Object[])-&amp;gt;&lt;br /&gt;01b116e8(MongoDB.Connections.RawConnection)&lt;/div&gt;&lt;p&gt;冒似是mongo连接池的队列一直在活动，导致RawConnetion没有被回收掉。看一下是不是RawConnection中Socket连接未关闭&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;:&lt;span style="color: #800080;"&gt;010&lt;/span&gt;&amp;gt; !dumpobj 01b32db4&lt;br /&gt;Name: MongoDB.Connections.RawConnection&lt;br /&gt;MethodTable: 008f0a10&lt;br /&gt;EEClass: 0086adc8&lt;br /&gt;Size: &lt;span style="color: #800080;"&gt;32&lt;/span&gt;(&lt;span style="color: #800080;"&gt;0x20&lt;/span&gt;) bytes&lt;br /&gt; (E:\MongGo\samus-mongodb-csharp-6397a0f\Demo\bin\Debug\MongoDB.dll)&lt;br /&gt;Fields:&lt;br /&gt;      MT    Field   Offset                 Type VT     Attr    Value Name&lt;br /&gt;517a9fd4  &lt;span style="color: #800080;"&gt;4000234&lt;/span&gt;        &lt;span style="color: #800080;"&gt;4&lt;/span&gt; ...Sockets.TcpClient  &lt;span style="color: #800080;"&gt;0&lt;/span&gt; instance 01b32dd4 _client&lt;br /&gt;&lt;span style="color: #800080;"&gt;00000000&lt;/span&gt;  &lt;span style="color: #800080;"&gt;4000235&lt;/span&gt;        &lt;span style="color: #800080;"&gt;8&lt;/span&gt;                       &lt;span style="color: #800080;"&gt;0&lt;/span&gt; instance 01b32e64 _authenticatedDatabases&lt;br /&gt;51b845b4  &lt;span style="color: #800080;"&gt;4000236&lt;/span&gt;       &lt;span style="color: #800080;"&gt;10&lt;/span&gt;       System.Boolean  &lt;span style="color: #800080;"&gt;1&lt;/span&gt; instance        &lt;span style="color: #800080;"&gt;0&lt;/span&gt; _isDisposed&lt;br /&gt;51b845b4  &lt;span style="color: #800080;"&gt;4000237&lt;/span&gt;       &lt;span style="color: #800080;"&gt;11&lt;/span&gt;       System.Boolean  &lt;span style="color: #800080;"&gt;1&lt;/span&gt; instance        &lt;span style="color: #800080;"&gt;0&lt;/span&gt; &amp;lt;IsInvalid&amp;gt;k__BackingField&lt;br /&gt;51b88148  &lt;span style="color: #800080;"&gt;4000238&lt;/span&gt;       &lt;span style="color: #800080;"&gt;14&lt;/span&gt;      System.DateTime  &lt;span style="color: #800080;"&gt;1&lt;/span&gt; instance 01b32dc8 &amp;lt;CreationTime&amp;gt;k__BackingField&lt;br /&gt;008f011c  &lt;span style="color: #800080;"&gt;4000239&lt;/span&gt;        c ...ngoServerEndPoint  &lt;span style="color: #800080;"&gt;0&lt;/span&gt; instance 01b401c8 &amp;lt;EndPoint&amp;gt;k__BackingField&lt;/div&gt;&lt;p&gt;-&amp;gt;gcroot&amp;nbsp; address&amp;nbsp; 01b32dd4&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;:&lt;span style="color: #800080;"&gt;010&lt;/span&gt;&amp;gt; !GCRoot 01b32dd4&lt;br /&gt;Note: Roots found on stacks may be &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt; positives. Run &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;!help gcroot&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;br /&gt;more info.&lt;br /&gt;Scan Thread &lt;span style="color: #800080;"&gt;0&lt;/span&gt; OSTHread &lt;span style="color: #800080;"&gt;1300&lt;/span&gt;&lt;br /&gt;Scan Thread &lt;span style="color: #800080;"&gt;2&lt;/span&gt; OSTHread a38&lt;br /&gt;Scan Thread &lt;span style="color: #800080;"&gt;3&lt;/span&gt; OSTHread 6b0&lt;br /&gt;Scan Thread &lt;span style="color: #800080;"&gt;5&lt;/span&gt; OSTHread 10b4&lt;br /&gt;DOMAIN(&lt;span style="color: #800080;"&gt;00215428&lt;/span&gt;):HANDLE(Pinned):1b13ec:Root:02a93250(System.Object[])-&amp;gt;&lt;br /&gt;01b31750(System.Collections.Generic.Dictionary`&lt;span style="color: #800080;"&gt;2&lt;/span&gt;[[System.String, mscorlib],[MongoDB.Connections.IConnectionFactory, MongoDB]])-&amp;gt;&lt;br /&gt;01b40210(System.Collections.Generic.Dictionary`&lt;span style="color: #800080;"&gt;2&lt;/span&gt;+Entry[[System.String, mscorlib],[MongoDB.Connections.IConnectionFactory, MongoDB]][])-&amp;gt;&lt;br /&gt;01b3fcbc(MongoDB.Connections.PooledConnectionFactory)-&amp;gt;&lt;br /&gt;01b3fcec(System.Collections.Generic.Queue`&lt;span style="color: #800080;"&gt;1&lt;/span&gt;[[MongoDB.Connections.RawConnection, MongoDB]])-&amp;gt;&lt;br /&gt;01b3308c(System.Object[])-&amp;gt;&lt;br /&gt;01b32db4(MongoDB.Connections.RawConnection)-&amp;gt;&lt;br /&gt;01b32dd4(System.Net.Sockets.TcpClient)&lt;/div&gt;&lt;p&gt;windbg对于调试非托管资源泄漏很方便，想了解更多读读这本书&lt;span style="color: #ff0000;"&gt;&amp;lt;CLRViaCS.第3版&amp;gt; .&lt;span style="color: #000000;"&gt; 书有点贵啊！详细windbg gc的调试可参照MSDN的这篇文章 &lt;a href="http://msdn.microsoft.com/zh-cn/magazine/cc163528.aspx" target="_blank"&gt;CLR 完全介绍: 研究内存问题&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 然而在实际应用很可能非托管资与托管资源是相互引用，所以就要按照一定的顺序来释放。.net 下提供了实现标准Dispose模式的IDisposable接口用以实现非托管资源的释放，当然你也可以自己手动释放，只要合理其实都一样。只是继承IDisposable我们多了选择，可以选择自己释放，也可以交由于GC代为管理。结合MSDN的例子，IDisposable的实现方式如下，详细介绍写在代码里。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Text;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt; ECEPDI.Utility&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #008000;"&gt;/*&lt;/span&gt;&lt;span style="color: #008000;"&gt;为什么有时候要使用IDisposable接口&lt;br /&gt;     * 因为我们的类中使用了非托管资源如COM接口，句柄等等，如你在使用完这些非托管资源能及时释放掉也不必实现IDisposable接口&lt;br /&gt;     * 或者，我们通过继承IDisposable接口后，在这个对象被使用完自己手动调用Dispose释放掉，或者等GC Finalize调用析构回收&lt;br /&gt;     *  &lt;br /&gt;     &lt;/span&gt;&lt;span style="color: #008000;"&gt;*/&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; MyResource:IDisposable&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Pointer to an external unmanaged resource.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; IntPtr handle;&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Other managed resource this class uses.&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;private Component component = new Component();&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Track whether Dispose has been called.&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; The class constructor.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; MyResource(IntPtr handle)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.handle = handle;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 垃圾回收器会通过析构函数调用Finalize回收FinalizeQueu对象(析构函数会被Finalize方法调用的)&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        ~MyResource()&lt;br /&gt;        {&lt;br /&gt;            Dispose(&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;);     &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;析构被编译后会加入try,catch包装 base.Finalize&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#region&lt;/span&gt; IDisposable 成员&lt;br /&gt;     &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 提供给使用者自己释放对象&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Dispose()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;由程序使用者自己释放对象&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            Dispose(&lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;因为调用者释放了对象，因此不需要垃圾回收器再次终结对象&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            GC.SuppressFinalize(&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 必须重复调用Dispose方法的标记&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; &lt;span style="background-color: #f5f5f5; font-family: Courier New;"&gt;disposed&lt;/span&gt; = &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 所有工作都由此方法完成&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; （其它方法都是调用此方法,为何设计此方法就是要把非托管资源手动释放掉，&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 析构和手动都要如此操作，只是手动操作还在主动把非托管资源释放掉)&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="disposing"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Dispose(&lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; disposing)&lt;br /&gt;        {           &lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.&lt;span style="background-color: #f5f5f5; font-family: Courier New;"&gt;disposed&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (disposing)&lt;br /&gt;                {&lt;br /&gt;                    &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;托管资源的释放--------------------------------&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;component.Dispose();&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;没有dispose方法就设置为null-------------------&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;                }&lt;br /&gt;&lt;br /&gt;                &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;-----------------------------------------------&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;此处释放非托管资源               &lt;br /&gt;                  &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;-----------------------------------------------&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;                CloseHandle(handle);&lt;br /&gt;                handle = IntPtr.Zero;&lt;br /&gt;                &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.disposed = &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Use interop to call the method necessary  &lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; to clean up the unmanaged resource.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        [System.Runtime.InteropServices.DllImport(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Kernel32&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;)]&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;extern&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Boolean CloseHandle(IntPtr handle);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 类似dbconnection Close方式释放对象 （其实调用的是Dispose)&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Close()&lt;br /&gt;        {&lt;br /&gt;            Dispose();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/div&gt;&lt;p&gt;实现IDisposable&amp;nbsp;接口后，我们有了两种方式释放对象中引用的资源，一种手动调用Dispose释放，另一种就是通过析构函数交由GC处理。&amp;nbsp;析构函数只是把我们dispose 非托管资源的代码交给GC Finalize调用，但是C#（或者其他的支持CLR的语言）中，由于GC的不确定性，析构方法被调用的时机我们无法确定，因此正常情况还是要我们及时手动的using或调用Dispose方法回收掉。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;strong&gt;PS:注意析构函数的对象，至少要两次以上GC.Collect()才能回收掉，第一次GC回收只做了一次移动标记的工作，第二次GC才认为此对象不可到达才真正回收。&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;strong&gt;当然你可以在程序结束时执行GC.Collect()，GC.WaitForPendingFinalizers()强制回收。&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;strong&gt;强调一下：调用Dispose释放对象，不是释放对象本身，而是释放对象引用的的资源（非托管以及托管资源，一般托管资源都是交给GC处理的）.调用Dispose的当前对象肯定属于活动对象，不可能在执行自己的Dispose时被释放或者被GC回收。当然我们可以在对象调用Dispose后，将其设置为null释放掉内存。&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;补充：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;:&lt;span style="color: #800080;"&gt;004&lt;/span&gt;&amp;gt; !dumpmt -md &lt;span style="color: #800080;"&gt;00194438&lt;/span&gt;&lt;br /&gt;EEClass: 006d6d28&lt;br /&gt;Module: &lt;span style="color: #800080;"&gt;00193488&lt;/span&gt;&lt;br /&gt;Name: MongoDB.Mongo&lt;br /&gt;mdToken: 020000ae  (E:\MongGo\samus-mongodb-csharp-&lt;span style="color: #800080;"&gt;0.90&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0.1&lt;/span&gt;\Demo\bin\Debug\MongoDB.dll)&lt;br /&gt;BaseSize: &lt;span style="color: #800080;"&gt;0x10&lt;/span&gt;&lt;br /&gt;ComponentSize: &lt;span style="color: #800080;"&gt;0x0&lt;/span&gt;&lt;br /&gt;Number of IFaces &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; IFaceMap: &lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;br /&gt;Slots &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; VTable: &lt;span style="color: #800080;"&gt;17&lt;/span&gt;&lt;br /&gt;--------------------------------------&lt;br /&gt;MethodDesc Table&lt;br /&gt;   Entry MethodDesc      JIT Name&lt;br /&gt;6f9e6a90   6f86494c   PreJIT System.Object.ToString()&lt;br /&gt;6f9e6ab0   6f864954   PreJIT System.Object.Equals(System.Object)&lt;br /&gt;6f9e6b20   6f864984   PreJIT System.Object.GetHashCode()&lt;br /&gt;6fa57540   6f8649a8   PreJIT System.Object.Finalize()&lt;br /&gt;0019c099   001943d0     NONE MongoDB.Mongo.Dispose()&lt;br /&gt;0019c09d   001943d8     NONE MongoDB.Mongo.get_ConnectionString()&lt;br /&gt;&lt;span style="color: #800080;"&gt;00593968&lt;/span&gt;   001943e0      JIT MongoDB.Mongo.GetDatabase(System.String)&lt;br /&gt;&lt;span style="color: #800080;"&gt;00593918&lt;/span&gt;   001943e8      JIT MongoDB.Mongo.get_Item(System.String)&lt;br /&gt;0019c0a9   001943f0     NONE MongoDB.Mongo.Connect()&lt;br /&gt;0019c0ad   001943f8     NONE MongoDB.Mongo.TryConnect()&lt;br /&gt;0019c0b1   &lt;span style="color: #800080;"&gt;00194400&lt;/span&gt;     NONE MongoDB.Mongo.Disconnect()&lt;br /&gt;0019c08d   001943b0     NONE MongoDB.Mongo..ctor()&lt;br /&gt;005901e8   001943b8      JIT MongoDB.Mongo..ctor(System.String)&lt;br /&gt;&lt;span style="color: #800080;"&gt;00591878&lt;/span&gt;   001943c4      JIT MongoDB.Mongo..ctor(MongoDB.Configuration.MongoConfiguration)&lt;br /&gt;0019c0b5   &lt;span style="color: #800080;"&gt;00194408&lt;/span&gt;     NONE MongoDB.Mongo.GetDatabases()&lt;br /&gt;0019c0b9   &lt;span style="color: #800080;"&gt;00194414&lt;/span&gt;     NONE MongoDB.Mongo.&amp;lt;GetDatabases&amp;gt;b__1(MongoDB.Document)&lt;br /&gt;0019c0bd   &lt;span style="color: #800080;"&gt;00194420&lt;/span&gt;     NONE MongoDB.Mongo.&amp;lt;GetDatabases&amp;gt;b__2(System.String)&lt;/div&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;留意JIT项，会发现很多项为NONE ，说是这些方法从未被调用过，故JIT函数从未编译这些项IL代码为CPU指令。PreJIT指这些方法被提前预编译好为本地指令。看一下下面JIT编译的相关信息&lt;/span&gt;&lt;/strong&gt;&lt;span style="color: #ff0000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #ff0000;"&gt;&lt;span style="text-decoration: underline;"&gt;&lt;span style="color: #000000; text-decoration: underline;"&gt; !&lt;/span&gt;&lt;span style="color: #000000;"&gt;u + md地址 查看JIT编译方法的相关信息&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;:&lt;span style="color: #800080;"&gt;004&lt;/span&gt;&amp;gt; !U 001943e0&lt;br /&gt;Normal JIT generated code&lt;br /&gt;MongoDB.Mongo.GetDatabase(System.String)&lt;br /&gt;Begin &lt;span style="color: #800080;"&gt;00593968&lt;/span&gt;, size 5b&lt;br /&gt;&lt;span style="color: #800080;"&gt;00593968&lt;/span&gt; &lt;span style="color: #800080;"&gt;55&lt;/span&gt;              push    ebp&lt;br /&gt;&lt;span style="color: #800080;"&gt;00593969&lt;/span&gt; 8bec            mov     ebp,esp&lt;br /&gt;0059396b 83ec14          sub     esp,14h&lt;br /&gt;0059396e 894dfc          mov     dword ptr [ebp-&lt;span style="color: #800080;"&gt;4&lt;/span&gt;],ecx&lt;br /&gt;&lt;span style="color: #800080;"&gt;00593971&lt;/span&gt; 8955f8          mov     dword ptr [ebp-&lt;span style="color: #800080;"&gt;8&lt;/span&gt;],edx&lt;br /&gt;&lt;span style="color: #800080;"&gt;00593974&lt;/span&gt; 833d4036190000  cmp     dword ptr ds:[193640h],&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;br /&gt;0059397b &lt;span style="color: #800080;"&gt;7405&lt;/span&gt;            je      &lt;span style="color: #800080;"&gt;00593982&lt;/span&gt;&lt;br /&gt;0059397d e8efdb1670      call    mscorwks!CorLaunchApplication+&lt;span style="color: #800080;"&gt;0xe99e&lt;/span&gt; (&lt;span style="color: #800080;"&gt;70701571&lt;/span&gt;) (JitHelp: CORINFO_HELP_DBG_IS_JUST_MY_CODE)&lt;br /&gt;&lt;span style="color: #800080;"&gt;00593982&lt;/span&gt; 33d2            xor     edx,edx&lt;br /&gt;&lt;span style="color: #800080;"&gt;00593984&lt;/span&gt; 8955f4          mov     dword ptr [ebp-0Ch],edx&lt;br /&gt;&lt;span style="color: #800080;"&gt;00593987&lt;/span&gt; &lt;span style="color: #800080;"&gt;90&lt;/span&gt;              nop&lt;br /&gt;&lt;span style="color: #800080;"&gt;00593988&lt;/span&gt; b908138f00      mov     ecx,8F1308h (MT: MongoDB.MongoDatabase)&lt;br /&gt;0059398d e88ae6baff      call    0014201c (JitHelp: CORINFO_HELP_NEWSFAST)&lt;br /&gt;&lt;span style="color: #800080;"&gt;00593992&lt;/span&gt; 8945f0          mov     dword ptr [ebp-10h],eax&lt;/div&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;通过dumpmt -md&amp;nbsp; +MT地址 可获取该类型下的所有方法信息&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;:&lt;span style="color: #800080;"&gt;004&lt;/span&gt;&amp;gt; !dumpmd 001943f0&lt;br /&gt;Method Name: MongoDB.Mongo.Connect()&lt;br /&gt;Class: 006d6d28&lt;br /&gt;MethodTable: &lt;span style="color: #800080;"&gt;00194438&lt;/span&gt;&lt;br /&gt;mdToken: 060005a9&lt;br /&gt;Module: &lt;span style="color: #800080;"&gt;00193488&lt;/span&gt;&lt;br /&gt;IsJitted: no&lt;br /&gt;CodeAddr: ffffffff&lt;/div&gt;&lt;p&gt;通过dumpmd&amp;nbsp; +methoddesc地址 获取方法的信息 &lt;br /&gt;0:004&amp;gt; !DumpModule 00193488&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (dumpModule +module地址)&amp;nbsp; 获取模块（dll,module）信息：模块中定义的类/模块引用的类&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;:&lt;span style="color: #800080;"&gt;004&lt;/span&gt;&amp;gt; !DumpAssembly 004727b0&lt;br /&gt;Parent Domain: &lt;span style="color: #800080;"&gt;00445598&lt;/span&gt;&lt;br /&gt;Name: E:\MongGo\samus-mongodb-csharp-&lt;span style="color: #800080;"&gt;0.90&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0.1&lt;/span&gt;\Demo\bin\Debug\MongoDB.dll&lt;br /&gt;ClassLoader: &lt;span style="color: #800080;"&gt;00472820&lt;/span&gt;&lt;br /&gt;SecurityDescriptor: 005b5f60&lt;br /&gt;  Module Name&lt;br /&gt;&lt;span style="color: #800080;"&gt;00193488&lt;/span&gt; E:\MongGo\samus-mongodb-csharp-&lt;span style="color: #800080;"&gt;0.90&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0.1&lt;/span&gt;\Demo\bin\Debug\MongoDB.dll&lt;br /&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;:&lt;span style="color: #800080;"&gt;004&lt;/span&gt;&amp;gt; !DumpAssembly 004727b0&lt;br /&gt;Parent Domain: &lt;span style="color: #800080;"&gt;00445598&lt;/span&gt;&lt;br /&gt;Name: E:\MongGo\samus-mongodb-csharp-&lt;span style="color: #800080;"&gt;0.90&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0.1&lt;/span&gt;\Demo\bin\Debug\MongoDB.dll&lt;br /&gt;ClassLoader: &lt;span style="color: #800080;"&gt;00472820&lt;/span&gt;&lt;br /&gt;SecurityDescriptor: 005b5f60&lt;br /&gt;  Module Name&lt;br /&gt;&lt;span style="color: #800080;"&gt;00193488&lt;/span&gt; E:\MongGo\samus-mongodb-csharp-&lt;span style="color: #800080;"&gt;0.90&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0.1&lt;/span&gt;\Demo\bin\Debug\MongoDB.dll&lt;/div&gt;&lt;p&gt;从methodTable/methodDesc 可以查出module信息 从dumpModule可获得assembly的信息&amp;nbsp; dumpAssembly 查询程序集相关信息&lt;br /&gt;&lt;br /&gt;不管是dumpmt/dumpmd&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;mdToken可以获得对应类型或方法的元数据4位字节的2进制标识&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;而MethodTable （元数据+IL被加载后的数据） 并且记录了所有方法的结构数据MethodsDesc（IL+CALL JIT/或者已经编译的本地CPU指令）&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;而MethodsDesc 则保存对应方法IL代码 以及指向JIT的地址，当首方法首先被调用，JIT会将IL编译成本地指令，并且保在MethodsDesc 中，&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;这样在下次调时就不必被JIT函数编译而直接执行。(我们平时代码中反射的程序集信息其实就是元数据)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;下面是JIT工作的具体方式：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Calling a method for the first time:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Your program code calls a method Foo()&lt;/li&gt;&lt;li&gt;The CLR looks at the type that implements Foo() and gets the metadata associated with it&lt;/li&gt;&lt;li&gt;From the metadata, the CLR knows what memory address the IL (Intermediate byte code) is stored in.&lt;/li&gt;&lt;li&gt;The CLR allocates a block of memory, and calls the JIT.&lt;/li&gt;&lt;li&gt;The JIT compiles the IL into native code, places it into the allocated memory, and then changes the function pointer in Foo()'s type metadata to point to this native code.&lt;/li&gt;&lt;li&gt;The native code is ran.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Calling a method for the second time:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Your program code calls a method Foo()&lt;/li&gt;&lt;li&gt;The CLR looks at the type that implements Foo() and finds the function pointer in the metadata.&lt;/li&gt;&lt;li&gt;The native code at this memory location is ran.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;当执行到某一个方法，CLR 根据从元数据（应该指的是MethodTable）查找到此方法地址（根据mdtoken找到MethodDesc，MethodDesc），CLR此时会从托管堆上分配空间，并且调用JIT 编译IL为本地CPU指令，并改变函数指针到这堆内存上执行本地CPU指令。&lt;/p&gt;&lt;p&gt;PS:在园子里看文章说debug/relased 两个模式编译的IL代码是一样的，但是IL经JIT编译本地指令的时候，released模式的指令被优化了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/mecity/aggbug/2226214.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/mecity/archive/2011/10/27/2226214.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/mecity/archive/2011/10/20/2219621.html</id><title type="text">JS图片素材及JQueryUI样式设计</title><summary type="text">白菜同志介绍了两个好的JS相关的素材网址，不错赞一个收藏了。http://www.easyicon.cn/ 图片素材网http://jqueryui.com/themeroller/ jqueryUI 样式设计，这个还有FireFox版本的设计器http://apycom.com/ 导航jcDock 防苹果桌面http://ndesign-studio.com/blog/css-dock-menuhttp://www.wizzud.com/jqDock/图片相关的http://leandrovieira.com/projects/jquery/lightbox/ jQuery lightBox</summary><published>2011-10-20T14:42:00Z</published><updated>2011-10-20T14:42:00Z</updated><author><name>小城岁月</name><uri>http://www.cnblogs.com/mecity/</uri></author><link rel="alternate" href="http://www.cnblogs.com/mecity/archive/2011/10/20/2219621.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/mecity/archive/2011/10/20/2219621.html"/><content type="html">&lt;p&gt;白菜同志介绍了两个好的JS相关的素材网址，不错赞一个收藏了。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.easyicon.cn/"&gt;http://www.easyicon.cn/&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 图片素材网&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/131283/2011102022444834.png" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="http://jqueryui.com/themeroller/"&gt;http://jqueryui.com/themeroller/&lt;/a&gt;&amp;nbsp;&amp;nbsp; jqueryUI 样式设计，这个还有FireFox版本的设计器&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;img alt="" src="http://pic002.cnblogs.com/images/2011/131283/2011102022450528.png" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;a href="http://apycom.com/"&gt;http://apycom.com/&lt;/a&gt;&amp;nbsp;&amp;nbsp; 导航&lt;/p&gt;&lt;p&gt;&amp;nbsp;jcDock 防苹果桌面&lt;/p&gt;&lt;p&gt;&lt;a href="http://ndesign-studio.com/blog/css-dock-menu"&gt;http://ndesign-studio.com/blog/css-dock-menu&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.wizzud.com/jqDock/"&gt;http://www.wizzud.com/jqDock/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;图片相关的&lt;/p&gt;&lt;p&gt;&lt;a href="http://leandrovieira.com/projects/jquery/lightbox/"&gt;http://leandrovieira.com/projects/jquery/lightbox/&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; jQuery lightBox plugin&lt;/p&gt;&lt;p&gt;&lt;a href="http://jqueryfordesigners.com/api-filter-find/"&gt;http://jqueryfordesigners.com/api-filter-find/&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 图片冒泡&lt;/p&gt;&lt;p&gt;&lt;a href="http://fancybox.net/"&gt;http://fancybox.net/&lt;/a&gt;&amp;nbsp;&amp;nbsp; 图片浏览&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;控件的就多了 easyui,extjs,jqgrid等等。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.cnblogs.com/andylaufzf/archive/2009/03/26/1422255.html"&gt;http://www.cnblogs.com/andylaufzf/archive/2009/03/26/1422255.html&lt;/a&gt;&amp;nbsp;&amp;nbsp; 博园朋友的大杂烩&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/mecity/aggbug/2219621.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/mecity/archive/2011/10/20/2219621.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
