<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="css/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>谷哥博客</title><link>http://guooge.com/</link><description>杭州网站优化|【谷哥博客】</description><generator>RainbowSoft Studio Z-Blog 1.8 Walle Build 100427</generator><language>zh-CN</language><copyright>联系邮箱：guooge@guooge.com&amp;amp;nbsp;网站地图	 谷哥 Powered by Z-blog      var _bdhmProtocol = ((&amp;quot;https:&amp;quot; == document.location.protocol) ? &amp;quot; https://&amp;quot; : &amp;quot; http://&amp;quot;);document.write(unescape(&amp;quot;%3Cscript src='&amp;quot; + _bdhmProtocol + &amp;quot;hm.baidu.com/h.js%3Fdcffded88313ae2931fa743051674a1d' type='text/javascript'%3E%3C/script%3E&amp;quot;));</copyright><pubDate>Tue, 08 May 2012 10:29:39 +0800</pubDate><item><title>写在成长的路上</title><author>a@b.com (谷哥)</author><link>http://guooge.com/archives/394.html</link><pubDate>Tue, 08 May 2012 09:30:32 +0800</pubDate><guid>http://guooge.com/archives/394.html</guid><description><![CDATA[<p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; 无数个夜晚，做着同一个梦。萦绕着成长与辉煌。</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;无数佧白天，现实被支离破碎的演绎，泛泛消褪，灿烂的锋艺。</p><p>&nbsp; &nbsp; &nbsp; &nbsp; 手握一杯醇醇的咖啡，坐在教室的角落的空前，默默地望着窗外的风景，思绪一点一点蔓延。想起《玻璃杯》里一句歌词：我又说我是一只玻璃杯，心痛的无言以对。就算是再洒脱笑得再美，心碎了要用什么来赔。多一佔爱就多一点疲惫，洒掉一些让自己放飞。让自己放飞？如何飞？脸上掠过一丝苦涩的笑容，一如手中咖啡的味道。啜一口，审视自己的平静，外界喧闹瞬间蒸发。岁月刹那间停刹。只静静的让灵魂自由的游走，品味成长的历程。</p><p>&nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp;我用潇洒伪装自己，用冷静和故作的成熟掩盖心痛。阳光洒满大地。地唯独照不亮心中那片小小的天地。渴望平静，却平静的让人寂寞，寂寞又来的如此可怕。真怕在这寂寞中将自己沦落。昔日的激情和壮志被吞噬，时间的脚步也似乎永远定格在这刻，压抑、崩溃、窒息。无法忍受，要努力将这一切打破！</p><p>&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; 不甘就这样在静默中死亡，真想为阳光着色，来驱除心中的阴霾。远离落寞，背上行囊，继续昂首阔步走向梦想的远方。所有的苦闷，所有的彷徨，轻轻退到一旁，给我自己的方向。不再辜负年华韶光，直达梦的天堂！成长的路上，我们需要坚强，光阴不觉，我们已悄然长大；韶华飞逝，我们已成为别人的肩膀。</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;每个人生命中不可避免的总有些忧郁彷徨纠缠着，无论哪个阶段，迷茫你前进的方向；不安现状的人总会为生活的平庸自寻烦恼，于是去追求、奋斗，碰壁再碰壁。当失败成为常态，雄心沦为无奈，整日的奔波奋斗却换来无起色的未来。这样的生活又有几人能坚持得下来？平庸的人生就是在反复的失败中放弃自己。</p><p>&nbsp; &nbsp; &nbsp; &nbsp;世界可以无奈，你却不能对生活撒娇耍赖。只有破罐才会破摔。天地无情，不会因你的弱小而对你备加表睐。要让世界知道你的存在，就必须从苦闷中彰显气概。尽情挥洒你的精彩。每个人都是磁场，放弃招来随落，坚持吸引希望。试问，谁不曾为未来迷惘？</p><p>&nbsp; &nbsp; &nbsp; 因为年轻，所以要自信。心系梦想，我心才会飞扬！赋予自己腾飞的翅膀，去远方自由闯荡。成长的路上，任你自由徜徉，不灭的永远是希望！谪仙李白曾经告诉我们；长风破浪会有时，直挂云帆济沧海。不妨循着古迹，站在前人的肩膀，让梦启航－－－乘千里长风，破万里巨浪，直抵成功的远方！</p>]]></description><category>个人随笔</category><comments>http://guooge.com/archives/394.html#comment</comments><wfw:comment>http://guooge.com/</wfw:comment><wfw:commentRss>http://guooge.com/feed.asp?cmt=394</wfw:commentRss><trackback:ping>http://guooge.com/cmd.asp?act=tb&amp;id=394&amp;key=bd89af4c</trackback:ping></item><item><title>request.servervariables 参数大全</title><author>a@b.com (谷哥)</author><link>http://guooge.com/archives/393.html</link><pubDate>Fri, 04 May 2012 07:49:08 +0800</pubDate><guid>http://guooge.com/archives/393.html</guid><description><![CDATA[<p>Request.ServerVariables(&quot;Url&quot;) <br />返回服务器地址</p><p>Request.ServerVariables(&quot;Path_Info&quot;) <br />客户端提供的路径信息</p><p>Request.ServerVariables(&quot;Appl_Physical_Path&quot;) <br />与应用程序元数据库路径相应的物理路径</p><p>Request.ServerVariables(&quot;Path_Translated&quot;) <br />通过由虚拟至物理的映射后得到的路径<br />Request.ServerVariables(&quot;Script_Name&quot;) <br />执行脚本的名称</p><p>Request.ServerVariables(&quot;Query_String&quot;) <br />查询字符串內容</p><p>Request.ServerVariables(&quot;Http_Referer&quot;) <br />请求的字符串內容</p><p>Request.ServerVariables(&quot;Server_Port&quot;) <br />接受请求的服务器端口号</p><p>Request.ServerVariables(&quot;Remote_Addr&quot;) <br />发出请求的远程主机的IP地址</p><p>Request.ServerVariables(&quot;Remote_Host&quot;) <br />发出请求的远程主机名称</p><p>Request.ServerVariables(&quot;Local_Addr&quot;) <br />返回接受请求的服务器地址</p><p>Request.ServerVariables(&quot;Http_Host&quot;) <br />返回服务器地址</p><p>Request.ServerVariables(&quot;Server_Name&quot;) <br />服务器的主机名、DNS地址或IP地址</p><p>Request.ServerVariables(&quot;Request_Method&quot;) <br />提出请求的方法比如GET、HEAD、POST等等</p><p>Request.ServerVariables(&quot;Server_Port_Secure&quot;)<br />如果接受请求的服务器端口为安全端口时，则为1，否则为0</p><p>Request.ServerVariables(&quot;Server_Protocol&quot;)<br />服务器使用的协议的名称和版本</p><p>Request.ServerVariables(&quot;Server_Software&quot;)<br />应答请求并运行网关的服务器软件的名称和版本</p><p>Request.ServerVariables(&quot;All_Http&quot;)<br />客户端发送的所有HTTP标头，前缀HTTP_</p><p>Request.ServerVariables(&quot;All_Raw&quot;)<br />客户端发送的所有HTTP标头,其结果和客户端发送时一样，没有前缀HTTP_</p><p>Request.ServerVariables(&quot;Appl_MD_Path&quot;)<br />应用程序的元数据库路径</p><p>Request.ServerVariables(&quot;Content_Length&quot;)<br />客户端发出內容的长度</p><p>Request.ServerVariables(&quot;Https&quot;)<br />如果请求穿过安全通道（SSL），则返回ON如果请求来自非安全通道，则返回OFF</p><p>Request.ServerVariables(&quot;Instance_ID&quot;)<br />IIS实例的ID号</p><p>Request.ServerVariables(&quot;Instance_Meta_Path&quot;)<br />响应请求的IIS实例的元数据库路径</p><p>Request.ServerVariables(&quot;Http_Accept_Encoding&quot;)<br />返回內容如：gzip,deflate</p><p>Request.ServerVariables(&quot;Http_Accept_Language&quot;)<br />返回內容如：en-us</p><p>Request.ServerVariables(&quot;Http_Connection&quot;)<br />返回內容：Keep-Alive</p><p>Request.ServerVariables(&quot;Http_Cookie&quot;)</p><p>Request.ServerVariables(&quot;Http_User_Agent&quot;)<br />返回內容：Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1)</p><p>Request.ServerVariables(&quot;Https_Keysize&quot;)<br />安全套接字层连接关键字的位数，如128</p><p>Request.ServerVariables(&quot;Https_Secretkeysize&quot;)<br />服务器验证私人关键字的位数如1024</p><p>Request.ServerVariables(&quot;Https_Server_Issuer&quot;)<br />服务器证书的发行者字段</p><p>Request.ServerVariables(&quot;Https_Server_Subject&quot;)<br />服务器证书的主题字段</p><p>Request.ServerVariables(&quot;Auth_Password&quot;)<br />当使用基本验证模式时，客户在密码对话框中输入的密码</p><p>Request.ServerVariables(&quot;Auth_Type&quot;)<br />是用户访问受保护的脚本时，服务器用於检验用户的验证方法</p><p>Request.ServerVariables(&quot;Auth_User&quot;)<br />代证的用户名</p><p>Request.ServerVariables(&quot;Cert_Cookie&quot;)<br />唯一的客户证书ID号</p><p>Request.ServerVariables(&quot;Cert_Flag&quot;)<br />客户证书标誌，如有客户端证书，则bit0为0如果客户端证书验证无效，bit1被设置为1</p><p>Request.ServerVariables(&quot;Cert_Issuer&quot;)<br />用户证书中的发行者字段</p><p>Request.ServerVariables(&quot;Cert_Keysize&quot;)<br />安全套接字层连接关键字的位数，如128</p><p>Request.ServerVariables(&quot;Cert_Secretkeysize&quot;)<br />服务器验证私人关键字的位数如1024</p><p>Request.ServerVariables(&quot;Cert_Serialnumber&quot;)<br />客户证书的序列号字段</p><p>Request.ServerVariables(&quot;Cert_Server_Issuer&quot;)<br />服务器证书的发行者字段</p><p>Request.ServerVariables(&quot;Cert_Server_Subject&quot;)<br />服务器证书的主题字段</p><p>Request.ServerVariables(&quot;Cert_Subject&quot;)<br />客户端证书的主题字段</p><p>Request.ServerVariables(&quot;Content_Type&quot;)<br />客户发送的form內容或HTTPPUT的数据类型</p><p>&nbsp;</p>]]></description><category>编程开发</category><comments>http://guooge.com/archives/393.html#comment</comments><wfw:comment>http://guooge.com/</wfw:comment><wfw:commentRss>http://guooge.com/feed.asp?cmt=393</wfw:commentRss><trackback:ping>http://guooge.com/cmd.asp?act=tb&amp;id=393&amp;key=86cb5d95</trackback:ping></item><item><title> 第二大当：就业 </title><author>a@b.com (谷哥)</author><link>http://guooge.com/archives/392.html</link><pubDate>Thu, 26 Apr 2012 09:28:20 +0800</pubDate><guid>http://guooge.com/archives/392.html</guid><description><![CDATA[<p>&nbsp;第二大当：就业&nbsp;</p><div>当有人终于开始感叹：当年当知青的时候，当有人下岗之后感到没有生路，只能静坐抗议却无人理会，只能沦落街头还被人编首歌嘲笑着人生豪迈，重头再来的时候。你可曾想过！他们也曾经和今天的白领一样风光！他们的收入和地位也曾经让周围的人艳羡不已？你可曾想过20年后的今天！你一样会和他们一样沦落街头，众叛亲离？！&nbsp;</div><div>&nbsp;</div><div>　　有人说嘿！你不知道有失业保险，养老保险，XX保险么？呵呵，我在北京漂泊N年，交了无数保险大概有好几万吧，但失业的时候跑断腿也没人给我啥保险，反而很多保险都被冻结了说我交得断断续续的，我简直又气得&hellip;&hellip;这还不算，你以为你到了60岁真的就可以拿到养老保险了吗？天上又不会掉钱！今天的老年人拿的退休金是我们在挣！而今天30-40岁的人通常都有好几个兄弟姐妹！意思就是，今天的老年人能在60岁拿到养老保险是因为有5个人供一个老人！而我们这一代老去之后则是一个人供我们两个老人！钱从哪里来？没得来！您要是能活到90岁估计能领到一些养老保险，嘿保重吧您。然而即使是这样，家长们还是疯了一样的把孩子往各种企事业国有单位里送，我身边就经常有这样的例子。我老家一个远房亲戚，找关系拖朋友，花了七万块钱通过公开招聘把儿子送进了交警队，干上合同制的police。一个月拿800块。结果第三年被竞争上岗给刷下来了。一家人哭哭啼啼，我说刷了好，你上那班一辈子挣不回那七万，赶紧先洗洗睡，改明再凑点钱做小生意去吧！没准还能赚点。&nbsp;</div><div>&nbsp;当年我毕业的时候，我不文明用语也是领着我抱着钱，把我往XX部送。我一看负责招工那人那德行，就忍不住的恶心，再一看薪水，不文明用语呀，我这不是白干10年不吃不喝才拿回成本。所以我私下威胁了那家伙一把，吓得那个大腹便便的X科长再也不敢招收我。我才得已：离家出走。&nbsp;</div><div>&nbsp;</div><div>　　我就想不明白？中国人咋就这么傻？这么迷信国字呢？醒醒吧，思维正常一点行不？做事之前自己算算合算不合算成不？&nbsp;</div><div>&nbsp;</div><div>　　还有那些年纪轻轻的小白领们，找工作最好把薪水要高点，别要医疗保险和啥保险，然后自己把钱存起来最保险，将来用得着。&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp;点评：就业和创业的问题上，每个人有不同的看法，这个没有法说，在创业的时候你很多时候是一分钱没有的，不过你很开心，工作的时候也许你很开心，能拿到工资。哪你会不会衡量你的价值呢？郎咸平能说出这样的话了，我很佩服！</div><div>&nbsp; &nbsp; &nbsp;</div>]]></description><category>个人随笔</category><comments>http://guooge.com/archives/392.html#comment</comments><wfw:comment>http://guooge.com/</wfw:comment><wfw:commentRss>http://guooge.com/feed.asp?cmt=392</wfw:commentRss><trackback:ping>http://guooge.com/cmd.asp?act=tb&amp;id=392&amp;key=f3875e2a</trackback:ping></item><item><title>中国人正在上的四大当－买房</title><author>a@b.com (谷哥)</author><link>http://guooge.com/archives/391.html</link><pubDate>Thu, 26 Apr 2012 09:21:20 +0800</pubDate><guid>http://guooge.com/archives/391.html</guid><description><![CDATA[<p>&nbsp;中国人正在上的四大当，你上了几个了？&mdash;&mdash;中国香港著名经济学家郎咸平&nbsp;</p><p><p>第一大当：买房&nbsp;</p><p>&nbsp;</p><p>　 &nbsp;买房意味着什么？意味着你拥有了一个属于自己的房子。是的，你是这样以为，但是在中国你并无法拥有这个房子，只是租给你而已。因为房子是你的,地不是你的,只是把土地使用权70年(从现在退70年那是抗日战争时期,谁见过那时候的房子?)。房子通常情况下30年左右就会遇上拆迁或者旧房改造。也就是说你花了买房的钱，却只能得到租房的实际效果。当然这还不是最坏的。最坏的是，当几十年后你发觉上当了！有一群流氓冲进你用一辈子积蓄买下的房子，画上一个大大的拆字！然后把你的家当全部当垃圾一样的仍出门外，不顾你的苦苦哀求，甚至还在报纸上给你按一个钉子户的臭名，任大众辱骂的时候你就会知道什么叫做绝望！&nbsp;</p><p>&nbsp;</p><p>　　形容中国的房地产有一个很有名的笑话是这样写的：&nbsp;</p><p>&nbsp;</p><p>　　以前，有个地主有很多地，找了很多长工干活，地主给长工们盖了一批团结楼住着，一天，地主的谋士对地主说：东家，长工们这几年手上有点钱了，他们住你的房子，每月交租子，不划算，反正他们永远住下去，你干脆把房子卖给他们起个名堂叫做&mdash;&mdash;公房出售！告诉他们房子永远归他们了，可以把他们这几年攒的钱收回来，地主说：不错，那租金怎么办？谋士说：照收不误，起个日本名儿，叫物业费！地主很快实行了，赚了好多钱，长工们那个高兴啊！&nbsp;</p><p>&nbsp;</p><p>　　过了几年，地主的村子发展成城镇了，有钱人越来越多，没地方住，谋士对地主说：东家，长工们这几年手上又有钱了，咱们给他们盖新房子，起个名堂叫做旧城改造，他们把手上的钱给我们，我们拆了房子盖新的，叫他们再买回去，可以多盖一些卖给别人，地主又实行了，这次，有些长工们不高兴了，地主的家丁派上用途了，长工们打掉牙只好往肚子里咽，地主又赚了好多钱。</p><p>&nbsp;</p><p>&nbsp; &nbsp; 又过了几年，地主的村子发展成大城市了，有钱人更多了，地主的土地更值钱了，谋士对地主说：东家，咱们把这些长工的房子拆了，在这个地方建别墅，拆出来的地盖好房子卖给那些有钱的大款还能赚一笔，地主说：长工们不干怎么办？谋士说：咱给他们钱多点儿，起个名堂叫货币化安置，咱再到咱们的猪圈旁边建房子，起个名堂叫经济适用房，给他们修个马车道让他们到那边买房住，地主说：他们钱不够怎么办？谋士说：从咱家的钱庄借前给他们，一年6分利，咱这钱还能生钱崽，又没风险，地主又实行了，长工们拿到钱，地主的经济适用房到现在才建了一间，长工们只好排队等房子，直到现在，还等着呢&hellip;&hellip;</p><p>&nbsp;</p><p>　　于是，长工们开始闹事了，地主有点慌，忙问谋士怎么办？谋士说：赶紧通知长工们，房子要跌价了，别买了，租房住吧，正好把我们的猪圈租给他们，结果，这么多年后，长工们的钱全没了，还在租房住，直到永远！&nbsp;</p><p>&nbsp;</p><p>　　这个笑话虽然有点夸张，但实际上这何尝又不是事实呢？有人说既然如此？为什么中国人还要买房？疯了一样的买？为什么？<span style="color: rgb(255, 0, 0); ">还不是愚民教育的结果</span>，就好象60 年代，鼓吹人们必须购买三大件：手表、缝纫机、自行车才算是成功人士才可嫁人娶妻。70年代鼓吹人们必须购买新四大件：电视，冰箱，洗衣机，装电话才算是出人头地才可娶妻生子一样，记得当年装电话可是要几千块钱一部啊（人均收入不到200的小城），而北京上海更有上万一部的时候，还得排队买号搭人情，和今天的买房又何其相似？</p><p>&nbsp;</p><p>而今天所有的狗屁学者又开始了这一套愚弄百姓的旧招：白领一族新标准，成功人士新选择X环X路小户型，X环X路商住型。收了你几十万后，还得每个月收你租金（新物业费），银行利息，以及各种巧立名目的加息、政策等等。总之不怕你不被整死，就怕你死得不够惨！老百姓咋就怎么乐于上当，而且百上不厌呢？我真是气得浑身都湿了！</p><p>&nbsp;点评：看清教育的现实，被教育了这多么年了，什么时候教你怎么去赚钱了，都是在教你怎么给别人赚钱。为什么会有愚民教育，没有SB 哪能有聪明人呢&nbsp;</p></p>]]></description><category>个人随笔</category><comments>http://guooge.com/archives/391.html#comment</comments><wfw:comment>http://guooge.com/</wfw:comment><wfw:commentRss>http://guooge.com/feed.asp?cmt=391</wfw:commentRss><trackback:ping>http://guooge.com/cmd.asp?act=tb&amp;id=391&amp;key=5185a071</trackback:ping></item><item><title>c# 获取网页源码可自动识别网站编码</title><author>a@b.com (谷哥)</author><link>http://guooge.com/archives/390.html</link><pubDate>Wed, 25 Apr 2012 08:10:06 +0800</pubDate><guid>http://guooge.com/archives/390.html</guid><description><![CDATA[<div class="codeText"><div class="codeHead">c# 获取网页源码可自动识别网站编码</div><div class="codeHead"><span class="lantxt">C# Code</span><span class="copyCodeText" style="cursor:pointer" onclick="copyIdText('code_3184')">复制内容到剪贴板</span></div><div id="code_3184"><ol start="1" class="dp-c">    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">string</span><span>&nbsp;GetHtml(</span><span class="keyword">string</span><span>&nbsp;url)&nbsp;&nbsp;</span></span></li>    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li>    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;GetHtml(url,&nbsp;</span><span class="keyword">null</span><span>);&nbsp;&nbsp;</span></span></li>    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//http://guooge.com</span><span>&nbsp;&nbsp;</span></span></li>    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//qq:313919848</span><span>&nbsp;&nbsp;</span></span></li>    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;获取网页的HTML内容，指定Encoding&nbsp;</span><span>&nbsp;&nbsp;</span></span></li>    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">static</span><span>&nbsp;</span><span class="keyword">string</span><span>&nbsp;GetHtml(</span><span class="keyword">string</span><span>&nbsp;url,&nbsp;Encoding&nbsp;encoding)&nbsp;&nbsp;</span></span></li>    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li>    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url&nbsp;=&nbsp;<span class="string">&quot;http://&quot;</span><span>&nbsp;+&nbsp;url;&nbsp;&nbsp;</span></span></li>    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">byte</span><span>[]&nbsp;buf&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;WebClient().DownloadData(url);&nbsp;&nbsp;</span></span></li>    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(encoding&nbsp;!=&nbsp;</span><span class="keyword">null</span><span>)&nbsp;</span><span class="keyword">return</span><span>&nbsp;encoding.GetString(buf);&nbsp;&nbsp;</span></span></li>    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">string</span><span>&nbsp;html&nbsp;=&nbsp;Encoding.UTF8.GetString(buf);&nbsp;&nbsp;</span></span></li>    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;encoding&nbsp;=&nbsp;GetEncoding(html);&nbsp;&nbsp;</span></li>    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(encoding&nbsp;==&nbsp;</span><span class="keyword">null</span><span>&nbsp;||&nbsp;encoding&nbsp;==&nbsp;Encoding.UTF8)&nbsp;</span><span class="keyword">return</span><span>&nbsp;html;&nbsp;&nbsp;</span></span></li>    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;encoding.GetString(buf);&nbsp;&nbsp;</span></span></li>    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>    <li><span>&nbsp;&nbsp;</span></li>    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;根据网页的HTML内容提取网页的Encoding&nbsp;</span><span>&nbsp;&nbsp;</span></span></li>    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">static</span><span>&nbsp;Encoding&nbsp;GetEncoding(</span><span class="keyword">string</span><span>&nbsp;html)&nbsp;&nbsp;</span></span></li>    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</span></li>    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">string</span><span>&nbsp;pattern&nbsp;=&nbsp;@</span><span class="string">&quot;(?i)\bcharset=(?&lt;charset&gt;[-a-zA-Z_0-9]+)&quot;</span><span>;&nbsp;&nbsp;</span></span></li>    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">string</span><span>&nbsp;charset&nbsp;=&nbsp;Regex.Match(html,&nbsp;pattern).Groups[</span><span class="string">&quot;charset&quot;</span><span>].Value;&nbsp;&nbsp;</span></span></li>    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">try</span><span>&nbsp;{&nbsp;</span><span class="keyword">return</span><span>&nbsp;Encoding.GetEncoding(charset);&nbsp;}&nbsp;&nbsp;</span></span></li>    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">catch</span><span>&nbsp;(ArgumentException)&nbsp;{&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">null</span><span>;&nbsp;}&nbsp;&nbsp;</span></span></li>    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;</span></li></ol></div></div><p>&nbsp;</p>]]></description><category>网络营销</category><comments>http://guooge.com/archives/390.html#comment</comments><wfw:comment>http://guooge.com/</wfw:comment><wfw:commentRss>http://guooge.com/feed.asp?cmt=390</wfw:commentRss><trackback:ping>http://guooge.com/cmd.asp?act=tb&amp;id=390&amp;key=0b5930b9</trackback:ping></item><item><title>c#线程专题笔记_基础篇一</title><author>a@b.com (谷哥)</author><link>http://guooge.com/archives/389.html</link><pubDate>Tue, 24 Apr 2012 22:09:46 +0800</pubDate><guid>http://guooge.com/archives/389.html</guid><description><![CDATA[<p><strong>&nbsp;怎样创建一个线程</strong></p><div>一）使用Thread类</div><div class="codeText"><div class="codeHead"><span class="lantxt">C# Code</span><span class="copyCodeText" style="cursor:pointer" onclick="copyIdText('code_5155')">复制内容到剪贴板</span></div><div id="code_5155"><ol start="1" class="dp-c">    <li class="alt"><span><span>ThreadStart&nbsp;threadStart=</span><span class="keyword">new</span><span>&nbsp;ThreadStart(Calculate);</span><span class="comment">//通过ThreadStart委托告诉子线程讲执行什么方法,这里执行一个计算圆周长的方法</span><span>&nbsp;&nbsp;</span></span></li>    <li><span>Thread&nbsp;thread=<span class="keyword">new</span><span>&nbsp;Thread(threadStart);&nbsp;&nbsp;</span></span></li>    <li class="alt"><span>thread.Start();&nbsp;<span class="comment">//启动新线程</span><span>&nbsp;&nbsp;</span></span></li>    <li><span>&nbsp;&nbsp;</span></li>    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;Calculate(){&nbsp;&nbsp;</span></span></li>    <li><span><span class="keyword">double</span><span>&nbsp;Diameter=0.5;&nbsp;&nbsp;</span></span></li>    <li class="alt"><span>Console.Write(<span class="string">&quot;The&nbsp;perimeter&nbsp;Of&nbsp;Circle&nbsp;with&nbsp;a&nbsp;Diameter&nbsp;of&nbsp;{0}&nbsp;is&nbsp;{1}&quot;</span><span>Diameter,Diameter*Math.PI);&nbsp;&nbsp;</span></span></li>    <li><span>}&nbsp;&nbsp;</span></li></ol></div></div><div>&nbsp;</div><div>&nbsp;</div><div>二）使用Delegate.BeginInvoke</div><div class="codeText"><div class="codeHead"><span class="lantxt">C# Code</span><span class="copyCodeText" style="cursor:pointer" onclick="copyIdText('code_1375')">复制内容到剪贴板</span></div><div id="code_1375"><ol start="1" class="dp-c">    <li class="alt">&nbsp;</li>    <div class="codeText">    <div class="codeHead"><span class="lantxt">C/C++ Code</span><span class="copyCodeText" style="cursor:pointer" onclick="copyIdText('code_4164')">复制内容到剪贴板</span></div>    <div id="code_4164">    <ol start="1" class="dp-cpp">        <li class="alt"><span><span class="comment">//线程调用的函数,给出直径作为参数,计算周长</span><span>&nbsp;&nbsp;</span></span></li>        <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="datatypes">double</span><span>&nbsp;Calculate(</span><span class="datatypes">double</span><span>&nbsp;Diameter)&nbsp;&nbsp;</span></span></li>        <li class="alt"><span>{&nbsp;&nbsp;</span></li>        <li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;Diameter&nbsp;*&nbsp;Math.PI;&nbsp;&nbsp;</span></span></li>        <li class="alt"><span>}&nbsp;&nbsp;</span></li>        <li><span>&nbsp;&nbsp;</span></li>        <li class="alt"><span><span class="comment">//线程完成之后回调的函数</span><span>&nbsp;&nbsp;</span></span></li>        <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;TaskFinished(IAsyncResult&nbsp;result)&nbsp;&nbsp;</span></span></li>        <li class="alt"><span>{&nbsp;&nbsp;</span></li>        <li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="datatypes">double</span><span>&nbsp;re&nbsp;=&nbsp;0;&nbsp;&nbsp;</span></span></li>        <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;re&nbsp;=&nbsp;calcMethod.EndInvoke(result);&nbsp;&nbsp;</span></li>        <li><span>&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(re);&nbsp;&nbsp;</span></li>        <li class="alt"><span>}&nbsp;&nbsp;</span></li>    </ol>    </div>    </div>    <div class="codeText">    <div class="codeHead"><span class="lantxt">C# Code</span><span class="copyCodeText" style="cursor:pointer" onclick="copyIdText('code_7062')">复制内容到剪贴板</span></div>    <div id="code_7062">    <ol start="1" class="dp-c">        <li class="alt"><span><span class="comment">//线程调用的函数,给出直径作为参数,计算周长</span><span>&nbsp;&nbsp;</span></span></li>        <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">double</span><span>&nbsp;Calculate(</span><span class="keyword">double</span><span>&nbsp;Diameter)&nbsp;&nbsp;</span></span></li>        <li class="alt"><span>{&nbsp;&nbsp;</span></li>        <li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;Diameter&nbsp;*&nbsp;Math.PI;&nbsp;&nbsp;</span></span></li>        <li class="alt"><span>}&nbsp;&nbsp;</span></li>        <li><span>&nbsp;&nbsp;</span></li>        <li class="alt"><span><span class="comment">//线程完成之后回调的函数</span><span>&nbsp;&nbsp;</span></span></li>        <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;TaskFinished(IAsyncResult&nbsp;result)&nbsp;&nbsp;</span></span></li>        <li class="alt"><span>{&nbsp;&nbsp;</span></li>        <li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">double</span><span>&nbsp;re&nbsp;=&nbsp;0;&nbsp;&nbsp;</span></span></li>        <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;re&nbsp;=&nbsp;calcMethod.EndInvoke(result);&nbsp;&nbsp;</span></li>        <li><span>&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(re);&nbsp;&nbsp;</span></li>        <li class="alt"><span>}&nbsp;</span></li>    </ol>    </div>    </div>    <li>&nbsp;</li></ol></div></div><div>&nbsp;</div><div>&nbsp;</div><div>&nbsp;</div><div>三）使用ThreadPool.QueueworkItem</div><div class="codeText"><div class="codeHead"><span class="lantxt">C/C++ Code</span><span class="copyCodeText" style="cursor:pointer" onclick="copyIdText('code_1872')">复制内容到剪贴板</span></div><div id="code_1872"><ol start="1" class="dp-cpp">    <li class="alt"><span><span>WaitCallback&nbsp;w&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;WaitCallback(Calculate);&nbsp;&nbsp;</span></span></li>    <li><span><span class="comment">//下面启动四个线程,计算四个直径下的圆周长</span><span>&nbsp;&nbsp;</span></span></li>    <li class="alt"><span>ThreadPool.QueueUserWorkItem(w,&nbsp;1.0);&nbsp;&nbsp;</span></li>    <li><span>ThreadPool.QueueUserWorkItem(w,&nbsp;2.0);&nbsp;&nbsp;</span></li>    <li class="alt"><span>ThreadPool.QueueUserWorkItem(w,&nbsp;3.0);&nbsp;&nbsp;</span></li>    <li><span>ThreadPool.QueueUserWorkItem(w,&nbsp;4.0);&nbsp;&nbsp;</span></li>    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;Calculate(</span><span class="datatypes">double</span><span>&nbsp;Diameter)&nbsp;&nbsp;</span></span></li>    <li><span>{&nbsp;&nbsp;</span></li>    <li class="alt"><span><span class="keyword">return</span><span>&nbsp;Diameter&nbsp;*&nbsp;Math.PI;&nbsp;&nbsp;</span></span></li>    <li><span>}&nbsp;&nbsp;</span></li></ol></div></div><div>&nbsp;</div><div>&nbsp;</div><div>受托管的线程与 Windows线程</div><div>必须要了解，执行.NET应用的线程实际上仍然是Windows线程。但是，当某个线程被CLR所知时，我们将它称为受托管的线程。具体来说，由受托管的代码创建出来的线程就是受托管的线程。如果一个线程由非托管的代码所创建，那么它就是非托管的线程。不过，一旦该线程执行了受托管的代码它就变成了受托管的线程。</div><div>一个受托管的线程和非托管的线程的区别在于，CLR将创建一个System.Threading.Thread类的实例来代表并操作前者。在内部实现中，CLR将一个包含了所有受托管线程的列表保存在一个叫做ThreadStore地方。</div><div>CLR确保每一个受托管的线程在任意时刻都在一个AppDomain中执行，但是这并不代表一个线程将永远处在一个AppDomain中，它可以随着时间的推移转到其他的AppDomain中。</div><div>从安全的角度来看，一个受托管的线程的主用户与底层的非托管线程中的Windows主用户是无关的。</div><div>&nbsp;</div><div>前台线程与后台线程</div><div>启动了多个线程的程序在关闭的时候却出现了问题，如果程序退出的时候不关闭线程，那么线程就会一直的存在，但是大多启动的线程都是局部变量，不能一一的关闭，如果调用Thread.CurrentThread.Abort()方法关闭主线程的话，就会出现ThreadAbortException 异常，因此这样不行。</div><div>后来找到了这个办法： Thread.IsBackground 设置线程为后台线程。</div><div>&nbsp;</div><div>msdn对前台线程和后台线程的解释：托管线程或者是后台线程，或者是前台线程。后台线程不会使托管执行环境处于活动状态，除此之外，后台线程与前台线程是一样的。一旦所有前台线程在托管进程（其中 .exe 文件是托管程序集）中被停止，系统将停止所有后台线程并关闭。通过设置 Thread.IsBackground 属性，可以将一个线程指定为后台线程或前台线程。例如，通过将 Thread.IsBackground 设置为 true，就可以将线程指定为后台线程。同样，通过将 IsBackground 设置为 false，就可以将线程指定为前台线程。从非托管代码进入托管执行环境的所有线程都被标记为后台线程。通过创建并启动新的 Thread 对象而生成的所有线程都是前台线程。如果要创建希望用来侦听某些活动（如套接字连接）的前台线程，则应将 Thread.IsBackground 设置为 true，以便进程可以终止。&nbsp;</div><div>所以解决办法就是在主线程初始化的时候，设置：Thread.CurrentThread.IsBackground = true;&nbsp;</div><div>&nbsp;</div><div>这样，主线程就是后台线程，在关闭主程序的时候就会关闭主线程，从而关闭所有线程。但是这样的话，就会强制关闭所有正在执行的线程，所以在关闭的时候要对线程工作的结果保存。</div><p>&nbsp;</p>]]></description><category>编程开发</category><comments>http://guooge.com/archives/389.html#comment</comments><wfw:comment>http://guooge.com/</wfw:comment><wfw:commentRss>http://guooge.com/feed.asp?cmt=389</wfw:commentRss><trackback:ping>http://guooge.com/cmd.asp?act=tb&amp;id=389&amp;key=8615354a</trackback:ping></item><item><title>winform 线程 异步执行</title><author>a@b.com (谷哥)</author><link>http://guooge.com/archives/388.html</link><pubDate>Tue, 24 Apr 2012 21:41:33 +0800</pubDate><guid>http://guooge.com/archives/388.html</guid><description><![CDATA[<p style="text-align: left; ">&nbsp;<span style="color: rgb(64, 50, 38); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 14px; line-height: 24px; ">(一）Control的Invoke和BeginInvoke</span></p><p style="margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 14px; color: rgb(64, 50, 38); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; line-height: 24px; text-align: left; ">我们要基于以下认识：<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />（1）Control的Invoke和BeginInvoke与Delegate的Invoke和BeginInvoke是不同的。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />（2）Control的Invoke和BeginInvoke的参数为delegate，委托的方法是在Control的线程上执行的，也就是我们平时所说的UI线程。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />我们以<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(128, 0, 128); ">代码(一)</span>来看(Control的Invoke)<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 255); ">private delegate void InvokeDelegate();<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />private void InvokeMethod(){<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp;//C代码段<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />private void butInvoke_Click(object sender, EventArgs e) {<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp;//A代码段.......<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp;this.Invoke(new InvokeDelegate(InvokeMethod));<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp;//B代码段......<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /></span>你觉得代码的执行顺序是什么呢?记好Control的Invoke和BeginInvoke都执行在主线程即UI线程上<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />A------&gt;C----------------&gt;B<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />解释：(1)A在UI线程上执行完后，开始Invoke，Invoke是同步<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />(2)代码段B并不执行，而是立即在UI线程上执行InvokeMethod方法，即代码段C。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />(3)Invok<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 0); ">eMethod方法执行完后，代码</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 0); ">段C才在UI线程上继续执行。</span><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(128, 0, 128); ">看看代码(二)，</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 0); ">Con</span>trol的BeginInvoke<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 255); ">private delegate void BeginInvokeDelegate();<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />private void BeginInvokeMethod(){<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp;//C代码段<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />private void butBeginInvoke_Click(object sender, EventArgs e) {<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp;//A代码段.......<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp;this.BeginInvoke(new BeginInvokeDelegate(BeginInvokeMethod));<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp;//B代码段......<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}</span><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />你觉得代码的执行顺序是什么呢?记好Control的Invoke和BeginInvoke都执行在主线程即UI线程上<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />A-----------&gt;B---------------&gt;C<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(255, 0, 0); ">慎重，这个只做参考。。。。。，我也不肯定执行顺序，如果有哪位达人知道的话请告知。</span><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />解释：：(1)A在UI线程上执行完后，开始BeginInvoke，BeginInvoke是异步<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />(2)InvokeMethod方法，即代码段C不会执行，而是立即在UI线程上执行代码段B。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />(3)代码段B执行完后(就是说butBeginInvoke_Click方法执行完后)，InvokeMethod方法，即代码段C才在UI线程上继续执行。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />由此，我们知道：<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />Control的Invoke和BeginInvoke的委托方法是在主线程，即UI线程上执行的。也就是说如果你的委托方法用来取花费时间长的数据，然后更新界面什么的，千万别在UI线程上调用Control.Invoke和Control.BeginInvoke，因为这些是依然阻塞UI线程的，造成界面的假死。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />那么，这个异步到底是什么意思呢?<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />异步是指相对于调用BeginInvoke的线程异步，而不是相对于UI线程异步，你在UI线程上调用BeginInvoke ，当然不行了。－－－－摘自&quot;Invoke和BeginInvoke的真正涵义&quot;一文中的评论。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />BeginInvoke的原理是将调用的方法Marshal成消息，然后调用Win32 API中的RegisterWindowMessage()向UI窗口发送消息。－－－－摘自&quot;Invoke和BeginInvoke的真正涵义&quot;一文中的评论。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />(二)我们用Thread来调用BeginInvoke和Invoke<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们开一个线程，让线程执行<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 0); ">一些耗费时间的操作，然后再用Control.Invoke和</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 0); ">Con</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 0); ">trol.BeginInvoke</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 0); ">回</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 0); ">到用户UI线程，执行界面</span>更新。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(128, 0, 128); ">&nbsp;代码(三)&nbsp; Thread调用Control的Invoke</span></p><p style="margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 14px; color: rgb(64, 50, 38); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; line-height: 24px; text-align: left; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 255); ">private Thread invokeThread;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />private delegate void invokeDelegate();<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />private void StartMethod(){<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; //C代码段......<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp;Control.Invoke(new invokeDelegate(invokeMethod));<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp; //D代码段......<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />private void invokeMethod(){<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp; //E代码段<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />private void butInvoke_Click(object sender, EventArgs e) {<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp;//A代码段.......<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; invokeThread = new Thread(new ThreadStart(StartMethod));<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; invokeThread.Start();<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp;//B代码段......<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}</span><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />你觉得代码的执行顺序是什么呢?记好Control的Invoke和BeginInvoke都执行在主线程即UI线程上<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />A------&gt;(Start一开始B和<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(255, 0, 0); ">StartMethod的</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(255, 0, 0); ">C</span>就同时执行)----&gt;(<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(255, 0, 0); ">C</span>执行完了，不管B有没有执行完，invokeThread把消息封送(invoke)给UI线程，然后自己等待)----&gt;UI线程处理完<font color="#0000ff" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">butInvoke_Click<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 0); ">消息后，处理invokeThread封送过来的消息，执行invokeMethod方法，即代码段E，处理往后UI线程切换到invokeThread线程。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />这个Control.Invoke是相对于invokeThread线程同步的，阻止了其运行。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><img border="0" alt="" src="http://guooge.com/upload/201204242143068107.JPG" width="958" height="610" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; border-style: initial; border-color: initial; " /><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />解释：<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />1。UI执行A<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />2。UI开线程InvokeThread，B和C同时执行，B执行在线程UI上，C执行在线程invokeThread上。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />3。invokeThread封送消息给UI，然后自己等待，UI处理完消息后，处理invokeThread封送的消息，即代码段E<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />4。UI执行完E后，转到线程invokeThread上，invokeThread线程执行代码段D<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /></span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(128, 0, 128); ">代码(四)&nbsp; Thread调用Control的BeginInvoke</span><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 0); "><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 255); ">private Thread beginInvokeThread;<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />private delegate void beginInvokeDelegate();<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />private void StartMethod(){<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; //C代码段......<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp;Control.BeginInvoke(new beginInvokeDelegate(beginInvokeMethod));<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp; //D代码段......<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />private void beginInvokeMethod(){<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp; //E代码段<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />private void butBeginInvoke_Click(object sender, EventArgs e) {<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp;//A代码段.......<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; beginInvokeThread = new Thread(new ThreadStart(StartMethod));<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp; beginInvokeThread .Start();<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />&nbsp;&nbsp;&nbsp;//B代码段......<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />}<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /></span>你觉得代码的执行顺序是什么呢?记好Control的Invoke和BeginInvoke都执行在主线程即UI线程上<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />A在UI线程上执行-----&gt;beginInvokeThread线程开始执行，UI继续执行代码段B，并发地invokeThread执行代码段C--------------&gt;不管UI有没有执行完代码段B，这时beginInvokeThread线程把消息封送给UI，单自己并不等待，继续向下执行--------&gt;UI处理完<font color="#0000ff" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">butBeginInvoke_Click<span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 0); ">消息后，处理beginInvokeThread线程封送过来的消息。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /></span></font></span></font></p><p style="margin-top: 5px; margin-right: auto; margin-bottom: 5px; margin-left: auto; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 14px; color: rgb(64, 50, 38); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; line-height: 24px; text-align: left; "><font color="#0000ff" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(0, 0, 0); "><font color="#0000ff" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><img border="0" alt="" src="http://guooge.com/upload/201204242143087788.JPG" width="802" height="466" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; border-style: initial; border-color: initial; " /><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />解释：<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />1。UI执行A<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />2。UI开线程beginInvokeThread，B和C同时执行，B执行在线程UI上，C执行在线程beginInvokeThread上。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />3。beginInvokeThread封送消息给UI，然后自己继续执行代码D，UI处理完消息后，处理invokeThread封送的消息，即代码段E<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><span style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(255, 0, 0); ">有点疑问：如果UI先执行完毕，是不是有可能过了段时间beginInvokeThread才把消息封送给UI，然后UI才继续执行封送的消息E。如图浅绿的部分。</span><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /><br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />Control的BeginInvoke是相对于调用它的线程，即beginInvokeThread相对是异步的。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />因此，我们可以想到。如果要异步取耗费长时间的数据，比如从数据库中读大量数据，我们应该这么做。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " /></span></font>(1)如果你想阻止调用线程，那么调用代码(三)，代码段D删掉，C改为耗费长时间的操作，因为这个操作是在另外一个线程中做的。代码段E改为更新界面的方法。<br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; " />(2)如果你不想阻止调用线程，那么调用代码(四)，代码段D删掉，C改为耗费长时间的操作，因为这个操作是在另外一个线程中做的。代码段E改为更新界面的方法。</span></font></p>]]></description><category>编程开发</category><comments>http://guooge.com/archives/388.html#comment</comments><wfw:comment>http://guooge.com/</wfw:comment><wfw:commentRss>http://guooge.com/feed.asp?cmt=388</wfw:commentRss><trackback:ping>http://guooge.com/cmd.asp?act=tb&amp;id=388&amp;key=f99f5285</trackback:ping></item><item><title>程序员需要思想</title><author>a@b.com (谷哥)</author><link>http://guooge.com/archives/387.html</link><pubDate>Tue, 24 Apr 2012 11:47:25 +0800</pubDate><guid>http://guooge.com/archives/387.html</guid><description><![CDATA[<p>&nbsp; &nbsp; &nbsp; &nbsp;谷哥一直在写程序，可就是没有能开发出一个完整的系统来，不是因为我没有这个能力，谷哥只是在寻找一个更好的方法，让程序更加完美，从执行效率，用户体验，SEO做到不错。</p><p>&nbsp; &nbsp; &nbsp; &nbsp;今天在博客园看了《程序员：挑战无处不在》谷哥明白了为什么我会在一个简单的用户登陆上浪费时间,以前我们写的哪些程序哪还叫程序吗？ 如果只是给客户来开发一个东西出来在不考虑效率的情况下，以.net 本身的优势，可以在很短的时间就能完成。谷哥是在给自己开发程序，所以有做到最好。在登陆的地方有什么是值得思考的呢？怎样写一个好的用户登录功能</p><p>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<img src="http://guooge.com/plugin/windsphoto/photo/20124/20124241234140.gif" alt="" title="" /></p><p>　　用户名和口令</p><p>　　首先，我们先来说说用户名和口令的事。这并不是本站第一次谈论这个事了。如何管理自己的口令让你知道怎么管理自己的口令，破解你的口令让你知道在现代这样速度的计算速度下，用穷举法破解你的口令可能会是一件很轻松的事。在这里我想告诉从开发者的角度上来做设计这个用户名和口令的事。下面一几件规则：</p><p>限制用户输入一些非常容易被破解的口令。如什么qwert，123456, password之类，就像twitter限制用户的口令一样做一个口令的黑名单。另外，你可以限制用户口令的长度，是否有大小写，是否有数字，你可以用你的程序做一下校验。当然，这可能会让用户感到很不爽，所以，现在很多网站都提供了UX让用户知道他的口令强度是什么样的（比如这个有趣的UX），这样可以让用户有一个选择，目的就是告诉用户&mdash;&mdash;要想安全，先把口令设得好一点。</p><p>千万不要明文保存用户的口令。正如如何管理自己的口令所说的一样，很多时候，用户都会用相同的ID相同的口令来登录很多网站。所以，如果你的网站明文保存的话，那么，如果你的数据被你的不良员工流传出去那对用户是灾难性的。所以，用户的口令一定要加密保存，最好是用不可逆的加密，如MD5或是SHA1之类的有hash算法的不可逆的加密算法。CSDN曾明文保存过用户的口令。（另，对于国内公司的品行以及有关部门的管理方式，我不敢保证国内网站以加密的方式保存你的口令。我觉得，做为一个有良知的人，我们应该加密保存用户的口令）</p><p>是否让浏览器保存口令。我们有N多的方法可以不让浏览器保存用户名和口令。但是这可能对用户来说很不爽。因为在真实世界里谁也记得不住那么多的口令。很多用户可能会使用一些密码管理工具来保存密码，浏览器只是其中一种。是否让浏览器保存这个需要你做决定，重点是看一下你的系统的安全级别是否要求比较高，如果是的话，则不要让浏览器保存密码，并在网站明显的位置告诉用户&mdash;&mdash;保存口令最安全的地方只有你的大脑。</p><p>口令在网上的传输。因为HTTP是明文协议，所以，用户名和口令在网上也是明文发送的，这个很不安全。你可以看看这篇文章你就明白了。要做到加密传输就必需使用HTTPS协议。但是，在中国还是有很多网站的Web登录方式还在使用ActiveX控件，这可能成为IE6还大量存在的原因。我通常理解为这些ActiveX控件是为了反键盘记录程序的。不过，我依然觉ActiveX控件不应该存在，因为在国外的众多安全很重要的站点上都看不到ActiveX的控件的身影。</p><p>　　用户登录状态</p><p>&nbsp;</p><p>　　首先，我想告诉大家的是，因为HTTP是无状态的协议，也就是说，这个协议是无法记录用户访问状态的，其每次请求都是独立的无关联的，一笔是一笔。而我们的网站都是设计成多个页面的，所在页面跳转过程中我们需要知道用户的状态，尤其是用户登录的状态，这样我们在页面跳转后我们才知道是否可以让用户有权限来操作一些功能或是查看一些数据。</p><p>&nbsp;</p><p>　　所以，我们每个页面都需要对用户的身份进行认证。当然，我们不可能让用户在每个页面上输入用户名和口令，这会让用户觉得我们的网站相当的SB。为了实现这一功能，用得最多的技术就是浏览器的cookie，我们会把用户登录的信息存放在客户端的cookie里，这样，我们每个页面都从这个cookie里获得用户是否登录的信息，从而达到记录状态，验证用户的目的。但是，你真的会用cookie吗？下面是使用cookie的一些原则。</p><p>&nbsp;</p><p>千万不要在cookie中存放用户的密码。加密的密码都不行。因为这个密码可以被人获取并尝试离线穷举。所以，你一定不能把用户的密码保存在cookie中。我看到太多的站点这么干了。</p><p>正确设计&ldquo;记住密码&rdquo;。这个功能简直就是一个安全隐患，我觉得并不是所有的程序员都知道怎么设计这个事。一般的设计是&mdash;&mdash;一时用户勾选了这个功能，系统会生成一个cookie，cookie包括用户名和一个固定的散列值，这个固定的散列值一直使用。这样，你就可以在所有的设备和客户上都可以登录，而且可以有多个用户同时登录。这个并不是很安全。下面是一些更为安全的方法供你参考：</p><p>（&mdash;&mdash;更新 2011/08/26，原文中有些小错误，并且说的不清楚，重新调整了一下&mdash;&mdash;）</p><p>　　1）在cookie中，保存三个东西&mdash;&mdash;用户名，登录序列，登录token。</p><p>&nbsp;</p><p>　　用户名：明文存放。</p><p>　　登录序列：一个被MD5散列过的随机数，仅当强制用户输入口令时更新（如：用户修改了口令）。</p><p>　　登录token：一个被MD5散列过的随机数，仅一个登录session内有效，新的登录session会更新它。</p><p>&nbsp;</p><p>　　2）上述三个东西会存在服务器上，服务器的验证用户需要验证客户端cookie里的这三个事。</p><p>&nbsp;</p><p>　　3）这样的设计会有什么样的效果，会有下面的效果，</p><p>&nbsp;</p><p>　　　　a）登录token是单实例登录。意思就是一个用户只能有一个登录实例。</p><p>&nbsp;</p><p>　　　　b）登录序列是用来做盗用行为检测的。如果用户的cookie被盗后，盗用者使用这个cookie访问网站时，我们的系统是以为是合法用户，然后更新&ldquo;登录token&rdquo;，而真正的用户回来访问时，系统发现只有&ldquo;用户名&rdquo;和&ldquo;登录序列&rdquo;相同，但是&ldquo;登录token&rdquo;不对，这样的话，系统就知道，这个用户可能出现了被盗用的情况，于是，系统可以清除并更改登录序列 和 登录token，这样就可以令所有的cookie失效，并要求用户输入口令。并给警告用户系统安全。</p><p>&nbsp;</p><p>　　4）当然，上述这样的设计还是会有一些问题，比如：同一用户的不同设备登录，甚至在同一个设备上使用不同的浏览器保登录。一个设备会让另一个设备的登录token和登录序列失效，从而让其它设备和浏览器需要重新登录，并会造成cookie被盗用的假象。所以，你在服务器服还需要考虑- IP 地址，</p><p>&nbsp;</p><p>　　　　a）如果以口令方式登录，我们无需更新服务器的&ldquo;登录序列&rdquo;和 &ldquo;登录token&rdquo;（但需要更新cookie）。因为我们认为口令只有真正的用户知道。</p><p>&nbsp;</p><p>　　　　b）如果 IP相同 ，那么，我们无需更新服务器的&ldquo;登录序列&rdquo;和 &ldquo;登录token&rdquo;（但需要更新cookie）。因为我们认为是同一用户有同一IP（当然，同一个局域网里也有同一IP，但我们认为这个局域网是用户可以控制的。网吧内并不推荐使用这一功能）。</p><p>&nbsp;</p><p>　　　　c）如果（IP不同 &amp;&amp;没有用口令登录），那么，&ldquo;登录token&rdquo;就会在多个IP间发生变化（登录token在两个或多个ip间被来来回回的变换），当在一定时间内达到一定次数后，系统才会真正觉得被盗用的可能性很高，此时系统在后台清除&ldquo;登录序列&rdquo;和&ldquo;登录token&ldquo;，让Cookie失效，强制用户输入口令（或是要求用户更改口令），以保证多台设备上的cookie一致。</p><p>&nbsp;</p><p>不要让cookie有权限访问所有的操作。否则就是XSS攻击，这个功能请参看新浪微博的XSS攻击。下面的这些功能一定要用户输入口令：</p><p>　　1）修改口令。</p><p>&nbsp;</p><p>　　2）修改电子邮件。（电子邮件通过用来找回用户密码）</p><p>&nbsp;</p><p>　　3）用户的隐私信息。</p><p>&nbsp;</p><p>　　4）用户消费功能。</p><p>&nbsp;</p><p>权衡Cookie的过期时间。如果是永不过期，会有很不错的用户体验，但是这也会让用户很快就忘了登录密码。如果设置上过期期限，比如2周，一个月，那么可能会好一点，但是2周和一个月后，用户依然会忘了密码。尤其是用户在一些公共电脑上，如果保存了永久cookie的话，等于泄露了帐号。所以，对于cookie的过期时间我们还需要权衡。</p><p>　　找回口令的功能</p><p>&nbsp;</p><p>　　找回口令的功能一定要提供。但是很多朋友并不知道怎么来设计这个功能。我们有很多找回口令的设计，下面我逐个点评一下。</p><p>&nbsp;</p><p>千万不要使用安全问答。事实证明，这个环节很烦人，而且用户并不能很好的设置安全问答。什么，我的生日啊，我母亲的生日，等等。因为今天的互联网和以前不一样了，因为SNS，今天的互联比以前更真实了，我可以上facebook，开心，人人网，LinkedIn查到你的很多的真实的信息。通过这些信息我可以使用安全问答来重设你的口令。这里需要说一下 Facebook，Facebook的安全问答很强大，还要你通过照片认人，呵呵。</p><p>不要重置用户的密码。因为这有可能让用户的密码遭到恶意攻击。当然，你要发个邮件给用户让其确认，用户点击邮件中的一个链接，你再重置。我并不推荐这样的方法，因为用户一般都会用笔记下来这个很难记的口令，然后登录系统，因为登录系统时使用了&ldquo;记住密码&rdquo;的功能，所以导致用户不会去修改密码，从而要么导到被写下来的密码被人盗取，要么又忘记了密码。</p><p>好一点的做法&mdash;&mdash;通过邮件自行重置。当用户申请找回口令功能的时候，系统生成一个MD5唯一的随机字串（可通过UID+IP+timestamp+随机数），放在数据库中，然后设置上时限（比如1小时内），给用户发一个邮件，这个连接中包含那个MD5的字串的链接，用户通过点击那个链接来自己重新设置新的口令。</p><p>更好一点的做法&mdash;&mdash;多重认证。比如：通过手机+邮件的方式让用户输入验证码。手机+邮件可能还不把握，因为手机要能会丢了，而我的手机可以访问我的邮箱。所以，使用U盾，SecureID（一个会变化的6位数token），或是通过人工的方式核实用户身份。当然，这主要看你的系统的安全级别了。</p><p>　　口令探测防守</p><p>&nbsp;</p><p>使用验证码。验证码是后台随机产生的一个短暂的验证码，这个验证码一般是一个计算机很难识别的图片。这样就可以防止以程序的方式来尝试用户的口令。事实证明，这是最简单也最有效的方式。当然，总是让用户输入那些肉眼都看不清的验证码的用户体验不好，所以，可以折中一下。比如Google，当他发现一个IP地址发出大量的搜索后，其会要求你输入验证码。当他发现同一个IP注册了3个以上的gmail邮箱后，他需要给你发短信方式或是电话方式的验证码。</p><p>用户口令失败次数。调置口令失败的上限，如果失败过多，则把帐号锁了，需要用户以找回口令的方式来重新激活帐号。但是，这个功能可能会被恶意人使用。最好的方法是，增加其尝试的时间成本（以前的这篇文章说过一个增加时间成本的解密算法）。如，两次口令尝试的间隔是5秒钟。三次以上错误，帐号被临时锁上30秒，5次以上帐号被锁1分钟，10次以上错误帐号被锁4小时&hellip;&hellip;</p><p>系统全局防守。上述的防守只针对某一个别用户。恶意者们深知这一点，所以，他们一般会动用&ldquo;僵尸网络&rdquo;轮着尝试一堆用户的口令，所以上述的那种方法可能还不够好。我们需要在系统全局域上监控所有的口令失败的次数。当然，这个需要我们平时没有受到攻击时的数据做为支持。比如你的系统，平均每天有5000次的口令错误的事件，那么你可以认为，当口令错误大幅超过这个数后，而且时间相对集中，就说明有黑客攻击。这个时候你怎么办？一般最常见使用的方法是让所有的用户输错口令后再次尝试的时间成本增加。</p><p>　　最后，再说一下，关于用户登录，使用第三方的 OAuth 和 OpenID 也不失为一个很不错的选择。</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;程序员要的是相思， 要的是分析问题的能力，有好多的问题在目前看来都不是哪么的合理。技术是需要改变的，在不同的时期，当你觉得昨天你的code 不是哪么的完美，哪么你就进步了。</p><p>&nbsp;</p>]]></description><category>编程开发</category><comments>http://guooge.com/archives/387.html#comment</comments><wfw:comment>http://guooge.com/</wfw:comment><wfw:commentRss>http://guooge.com/feed.asp?cmt=387</wfw:commentRss><trackback:ping>http://guooge.com/cmd.asp?act=tb&amp;id=387&amp;key=9570d994</trackback:ping></item><item><title>ASP.NET中怎样才能使自己的代码运行的效率更高？</title><author>a@b.com (谷哥)</author><link>http://guooge.com/archives/386.html</link><pubDate>Sun, 22 Apr 2012 01:27:01 +0800</pubDate><guid>http://guooge.com/archives/386.html</guid><description><![CDATA[<p>在使用asp.net开发网站的时候谷哥一直在考虑要怎么才能使网站的运行速度更高,只有效率高了对于SEO.用户体验才能更好.更利于网站的排名.</p><p>&nbsp;一、网页设计相关：</p><div>1，做好页面布局和内容规划，只放置合适的内容，并尽可能使页面设计的最小。</div><div>2，使用好的网页编辑器，如DW，FP，不要用VS自带的编辑器，因为它会产生很多无用的沉余代码，而且设计的界面也不是很好看。</div><div>3，小图片采用GIF格式，下载速度最快，大一点的采用jpg,占用磁盘空间小。</div><div>4，尽可能使用CSS，这既是原则也是方法，可以使整个网站浏览速度提高3%以上，有的甚至能够提高30% 。</div><div>5，尽量不要使用框架，在需要的地方也要有替代措施。</div><div>6，不要只针对IE写客户端脚本。</div><div>7，客户端的事情尽量在客户端处理。现在客户端设备已经很强了，许多原来在服务器端才能做的事情现在都能在客户端做，而服务器端反而成了访问的瓶颈。</div><div>8，少用Flash。Flash一般都会占较大的网络带宽，在需要的时候也要注意不要做得太大用的太多。</div><div>9， 避免使用弹出式对话框，因为现在好多浏览器都被装上了&ldquo;弹出窗口拦截&rdquo;插件。说服用户解决这个问题有时是很恼火的，因为他们不是都能熟练的使用计算机。</div><div>二、.NET设计相关&nbsp;</div><div>1，能用Label的地方不用TextBox，因为Label比起TextBox来说是轻量级的控件。</div><div>2，尽量使用Repeater 控件绑定列表数据，有两个原因，一是可以保留美工原始的界面设计效果，二是比起DataGrid控件，性能可以提升70%（有专门的测试案例）。</div><div>3，如果页面仅仅是浏览不用回送服务器端继续处理，那么不要使用页面视图ViewState。如果一个界面上有很多控件那么视图将会占去一半的页面大小。其他情况也要尽量少用页面视图。</div><div>4，采用缓存技术。从缓存位置可以分为客户端缓存、代理缓存、服务器端缓存；从具体页面来说可以分为整页缓存、局部缓存、数据缓存。缓存技术可以极大地提高Web服务器的处理能力，是最经济有效的提高访问速度的措施。</div><div>5，静态页面生成技术。如果采用缓存不能起到很好的作用那么可以将经常访问的页面生成静态页面。像三大门户网站都采用了这个技术，很多CMS也都采用了该技术。</div><div>6，服务器处理数据，客户端负责展现。把客户端的事件放到服务器端去处理在互联网上不是好注意，不能想象这是一个企业内部的Web应用程序。</div><div>7， 少用Session。如果要在页面之间传递参数，可以采用URL方式或者页面视图方式，如果是跨页面的数据传递，那么也最好使用Cookie 。Web访 问的特点决定了这个多用户并发访问环境，Session会占用很多服务器资源，如果访问量很大这个资源占用是很高的。</div><div>8，合理使用Application 。不同于缓存对象，它能够提供更好的全局数据访问，适合于需要长时间缓存频繁的公共数据。</div><div>9，注意Cookie 问题，有的浏览器可能不支持使用Cookie 访问你的站点，在使用Cookie 之前一定要检测客户端是否支持并采用相应的策略。</div><div>10， 只访问需要的数据，现在Ajax技术可以很好的处理这类问题，它让页面处理速度更快表现力更丰富。</div><div>&nbsp;</div><div>三、数据访问相关&nbsp;</div><div>1，优化数据库结构设计。这是数据访问效率和编程复杂程度的关键。没有良好的数据库结构设计其它都谈不上。包括字段类型的选择，表的结构，索引的使用，表的关系等。</div><div>2，优化数据库物理设计。这里关注的是数据库容量，日志，磁盘使用，数据备份机制，数据访问机制，安全等数据库物理结构相关的问题。</div><div>3，合理设计&ldquo;主键&rdquo;：在不同的场合需要采用不同的主键设计策略，在互联网大容量并发访问的环境中，建议主键采用整形自增字段。主键使用还应该遵循&ldquo;无意义&rdquo;原则。</div><div>4，采用最佳的数据访问接口，如专门针对SQL Server的数据访问对象。</div><div>5，&ldquo;只要需要的数据&rdquo;：如果一行有大容量字段，那么读取一整行效率是非常低的（数据瓶颈）。</div><div>6，最迟打开，最早关闭的原则。使用数据库后一定要及时关闭连接，它们是系统昂贵的资源。</div><div>7，采用&ldquo;数据缓存&rdquo;技术，将经常使用数据集缓存在磁盘或者内存中，尽量减少对数据库的直接访问。</div><div>8， 使用存储过程。可能在一般的应用系统中存储过程可以被简单的查询替代，因而更&ldquo;通用&rdquo;，但是我们现在讨论的是大型企业信息门户网站的问题。作为一个互联网 应用系统，处理速度和网络带宽无疑是最重要的。系统的瓶颈往往是磁盘IO和网络IO，合理使用存储过程使得分布式系统结构效率大大提升。但也要注意合理使 用，比如避免一般的分页过程，由于查询会有很多，使得这样的存储过程太多而管理混乱。</div><div>9，慎用游标。数据库的游标执行效率一般都比较低，一般都可以使用复杂的查询语句代替，合理的数据库结构设计也可以避免这个问题。</div><div>10，合理使用触发器。大部分人觉得触发器使得数据关系不明确，即屏蔽了数据的关系，但是当一个系统非常复杂的时候，数据关系更是复杂，这时候使用触发器来维护数据的一致性和数据同步的功能，可以有效地屏蔽数据关系的复杂性，减少程序代码。</div><div>11，合理使用事务：如果不是需要连续处理的或者需要特别安全的数据处理，不要使用事务，因为事务的使用会影响数据库的并发性能。单纯的查询过程也使用事务更不可取。</div><div>12，安全的数据访问：目前十分常见SQL注入式攻击，需要注意数据库系统安全设置和Web程序编码问题引起的安全漏洞。</div>]]></description><category>编程开发</category><comments>http://guooge.com/archives/386.html#comment</comments><wfw:comment>http://guooge.com/</wfw:comment><wfw:commentRss>http://guooge.com/feed.asp?cmt=386</wfw:commentRss><trackback:ping>http://guooge.com/cmd.asp?act=tb&amp;id=386&amp;key=8c4e1b94</trackback:ping></item><item><title>黑色气球也能升起</title><author>a@b.com (谷哥)</author><link>http://guooge.com/archives/385.html</link><pubDate>Fri, 20 Apr 2012 09:23:03 +0800</pubDate><guid>http://guooge.com/archives/385.html</guid><description><![CDATA[<p>&nbsp;今日小故事《黑色气球也能升起》</p><div>&nbsp; &nbsp; 一天，几个白人小孩正在公园里玩，这时，一位卖氢气球的老人推着货车进了公园。白人小孩一窝蜂地跑了过去，每人买了一个，兴高采烈地追逐着放飞在天空中的色彩艳丽的氢气球。在公园的一个角落躺着一个黑人小孩，他羡慕地看着白人小孩在嬉戏，不敢过去和他们一起玩，因为他很自卑。白人小孩的身影消失后，他才怯生生地走到老人的货车旁，用略带恳求的语气问道：&ldquo;您可以卖一个气球给我吗?&rdquo;老人用慈祥的目光打量了他一下，温和地说：&ldquo;当然可以，你要一个什么颜色的?&rdquo;小孩鼓起勇气回答说：&ldquo;我要一个黑色的。&rdquo;脸上写满沧桑的老人惊诧地看了看黑人小孩，旋即给了他一个黑色的氢气球。&nbsp;</div><div>&nbsp; &nbsp; 黑人小孩开心地拿过气球，小手一松，黑色气球在微风中冉冉升起，在蓝天白云的映衬下形成了一道别样的风景。&nbsp;</div><div>&nbsp; &nbsp; 老人一边眯着眼睛看气球上升，一边用手轻轻地拍了拍黑人小孩的后脑勺，说：&ldquo;记住，气球能不能升起，不是因为它的颜色、形状，而是气球内有没有充满氢气。一个人的成败不是因为种族、出身，关键是你的心中有没有自信。&rdquo;</div><div>&nbsp;</div>]]></description><category>网络文摘</category><comments>http://guooge.com/archives/385.html#comment</comments><wfw:comment>http://guooge.com/</wfw:comment><wfw:commentRss>http://guooge.com/feed.asp?cmt=385</wfw:commentRss><trackback:ping>http://guooge.com/cmd.asp?act=tb&amp;id=385&amp;key=dd728044</trackback:ping></item></channel></rss>

