<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://lonetear.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang=""><title type="html">CoCoMan Technology</title><subtitle type="html">all about computer science</subtitle><id>http://lonetear.com/blogs/cocoman/atom.aspx</id><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/default.aspx" /><link rel="self" type="application/atom+xml" href="http://lonetear.com/blogs/cocoman/atom.aspx" /><generator uri="http://communityserver.org" version="2.1.60809.935">Community Server</generator><updated>2007-11-16T21:56:00Z</updated><entry><title>转：疯人疯语之程序员版</title><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/archive/2008/02/28/_6C8F1AFFAF75BA4EAF75ED8B4B4E0B7A8F5E58544872_.aspx" /><id>http://lonetear.com/blogs/cocoman/archive/2008/02/28/_6C8F1AFFAF75BA4EAF75ED8B4B4E0B7A8F5E58544872_.aspx</id><published>2008-02-28T02:13:00Z</published><updated>2008-02-28T02:13:00Z</updated><content type="html">&amp;gt;写就要写最难懂的程序 &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;用记事本做编辑器 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;编译就得用最难用的编译器 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;程序不带半点注释 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;程序里面至少要有三个类 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;什么多继承呀, 多线程呀，template呀，inline呀 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;能给他用的全给他用上一行里面有while有++有?:有goto &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;文章里面一定要搬出一个XX哥 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;用很随意的语气，关系特好的样子 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;如果自己出书 ，甭管是什么语言 一开头都打印&amp;ldquo;hello world! &amp;rdquo; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;一副专业人士的派头(儿) &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;倍(儿)有感觉 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;编程中场再去冲杯咖啡 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;咖啡要雀巢的 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;一个程序最多也就一两个小时就搞定 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;最后再来句&amp;ldquo;最近感冒了，哎～&amp;rdquo; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;就一个字(儿)　酷 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;用下你写的程序就得要跟七八十个参数 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;同行的人不是用C就是用汇编 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;你要是用VB &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;你都不好意思跟人家打招呼你说这样的高手，一个月得拿多少钱？ &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;我觉得怎么着也得两千吧 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;两千 那是老板 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;五百封顶 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;你别嫌少　还是日元 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;你得理解老板的处境 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;本来公司就经营的惨不忍睹 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;根本不会再多给你一分钱 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;什么叫编程高手　你知道吗？ &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;编程高手就是写什么程序 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;都写最难的　不写最好的 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;所以，我们编程的口号(儿)就是 &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;gt;不求好用　但求难懂&amp;nbsp;&lt;/p&gt;&lt;img src="http://lonetear.com/aggbug.aspx?PostID=6286" width="1" height="1"&gt;</content><author><name>cocoman</name><uri>http://lonetear.com/members/cocoman.aspx</uri></author><category term="疯人疯语" scheme="http://lonetear.com/blogs/cocoman/archive/tags/_AF75BA4EAF75ED8B_/default.aspx" /></entry><entry><title>将AutoCompleteExtender的Service Method改为Page Method</title><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/archive/2008/01/10/_065C_AutoCompleteExtender_8476_Service-Method_39653A4E_Page-Method.aspx" /><id>http://lonetear.com/blogs/cocoman/archive/2008/01/10/_065C_AutoCompleteExtender_8476_Service-Method_39653A4E_Page-Method.aspx</id><published>2008-01-10T08:28:00Z</published><updated>2008-01-10T08:28:00Z</updated><content type="html">&lt;p&gt;使用Asp.net的AutoCompleteExtender时，默认情况下必须使用Web Service（即Service Method）来获得下拉框的数据。除了这种方式，其实也可以直接使用Page Method来获得数据。&lt;/p&gt;&lt;p&gt;1）去掉ServicePath属性。例如：&lt;/p&gt;&lt;p&gt;&amp;lt;cc1:AutoCompleteExtender runat=&amp;quot;server&amp;quot; &lt;br /&gt;&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; BehaviorID=&amp;quot;AutoCompleteToCo&amp;quot;&lt;br /&gt;&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; ID=&amp;quot;AutoCompleteExtender1&amp;quot; &lt;br /&gt;&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; TargetControlID=&amp;quot;txtToCo&amp;quot;&lt;br /&gt;&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; ServiceMethod=&amp;quot;GetDocumentToCo&amp;quot;&lt;br /&gt;&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; MinimumPrefixLength=&amp;quot;1&amp;quot; &lt;br /&gt;&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; CompletionInterval=&amp;quot;100&amp;quot;&lt;br /&gt;&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; EnableCaching=&amp;quot;true&amp;quot;&lt;br /&gt;&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; CompletionSetCount=&amp;quot;10&amp;quot;&lt;/p&gt;&lt;p&gt;2）在aspx.cs页面里加入静态函数。即：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [System.Web.Services.WebMethod]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public &lt;font color="#ff0000"&gt;static&lt;/font&gt; string[] GetDocumentToCo(string prefixText, int count)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //实现方法省略&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p&gt;注意：该方法是static的&lt;/p&gt;&lt;p&gt;这样即可使用Page Method。使用Page Method的好处是在函数中使用Page里的控件，与页面中的业务逻辑较好的结合，缺点是每次调用Page Method，实际上都产生了一次PostBack，效率不高。因此可根据实际需要进行选择，一般情况下，如果用AutoComplete的地方不多，我宁愿直接用Page method，懒得再建一个web service&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://lonetear.com/aggbug.aspx?PostID=6272" width="1" height="1"&gt;</content><author><name>cocoman</name><uri>http://lonetear.com/members/cocoman.aspx</uri></author><category term="Ajax" scheme="http://lonetear.com/blogs/cocoman/archive/tags/Ajax/default.aspx" /><category term="AutoCompleteExtender" scheme="http://lonetear.com/blogs/cocoman/archive/tags/AutoCompleteExtender/default.aspx" /></entry><entry><title>GridView的DataFormatString属性设置无效的解决办法</title><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/archive/2008/01/10/GridView_8476_DataFormatString_5E5C2760BE8B6E7FE06548658476E389B3519E52D56C_.aspx" /><id>http://lonetear.com/blogs/cocoman/archive/2008/01/10/GridView_8476_DataFormatString_5E5C2760BE8B6E7FE06548658476E389B3519E52D56C_.aspx</id><published>2008-01-10T08:24:00Z</published><updated>2008-01-10T08:24:00Z</updated><content type="html">&lt;p&gt;将该Column的HtmlEncode属性设为false。例如：&lt;/p&gt;&lt;p&gt;&amp;lt;asp:BoundField DataField=&amp;quot;RecordDate&amp;quot; HeaderText=&amp;quot;记录日期&amp;quot; DataFormatString=&amp;quot;{0:d}&amp;quot; HtmlEncode=&amp;quot;False&amp;quot; /&amp;gt;&lt;/p&gt;&lt;img src="http://lonetear.com/aggbug.aspx?PostID=6271" width="1" height="1"&gt;</content><author><name>cocoman</name><uri>http://lonetear.com/members/cocoman.aspx</uri></author><category term="DataFormatString" scheme="http://lonetear.com/blogs/cocoman/archive/tags/DataFormatString/default.aspx" /></entry><entry><title>How to install a .NET assemely into GAC</title><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/archive/2007/11/16/How-to-install-a-.NET-assemely-into-GAC.aspx" /><id>http://lonetear.com/blogs/cocoman/archive/2007/11/16/How-to-install-a-.NET-assemely-into-GAC.aspx</id><published>2007-11-16T14:30:00Z</published><updated>2007-11-16T14:30:00Z</updated><content type="html">Copy the dll file (e.g. xxx.dll) to c:\windows\system32&lt;br /&gt;&amp;bull; Open a command prompt&lt;br /&gt;&amp;bull; Go to C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin&lt;br /&gt;&amp;bull; Type this command:&lt;br /&gt;􀂃 &lt;font color="#ff0000"&gt;gacutil &lt;/font&gt;/i c:\windows\system32\xxx.dll&lt;br /&gt;􀂃 Press enter&lt;br /&gt;&lt;div&gt;done.&amp;nbsp;&lt;/div&gt;&lt;img src="http://lonetear.com/aggbug.aspx?PostID=45" width="1" height="1"&gt;</content><author><name>cocoman</name><uri>http://lonetear.com/members/cocoman.aspx</uri></author><category term=".Net" scheme="http://lonetear.com/blogs/cocoman/archive/tags/.Net/default.aspx" /></entry><entry><title>在存储过程中的动态查询</title><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/archive/2007/11/16/_2857585BA850C78F0B7A2D4E8476A8520160E567E28B_.aspx" /><id>http://lonetear.com/blogs/cocoman/archive/2007/11/16/_2857585BA850C78F0B7A2D4E8476A8520160E567E28B_.aspx</id><published>2007-11-16T14:26:00Z</published><updated>2007-11-16T14:26:00Z</updated><content type="html">&lt;div&gt;在存储过程过程中，如果要实现Select查询的where子句动态查询，可以用&lt;/div&gt;&lt;div&gt;exec ( &amp;quot;select .... where&amp;quot; +@whereStr)&lt;/div&gt;&lt;div&gt;这样的方式。但这样的话，感觉用存储过程就没什么用了，因为存储过程最大的特点就是将代码编译了放在DBMS中，而调用exec的话，这一部分就无法编译，也就无从优化了。&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;下面是一个比较巧妙的方法去实现所谓的&amp;ldquo;动态查询&amp;rdquo;&lt;/div&gt;&lt;div&gt;select * from table1 where&lt;/div&gt;&lt;div&gt;&amp;nbsp; a = 1&lt;/div&gt;&lt;div&gt;&amp;nbsp; and ( (@id is not null) or (id=@id) )&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;@id是传入的参数，如果◎id的值是null的话，那么and后面一整块是false，可以忽略，而如果不为null的话，实际上等于&lt;/div&gt;&lt;div&gt;where a=1 and id=@id&lt;/div&gt;&lt;div&gt;so...如果要启用id作为查询条件，就传入一个非null的值，否则就是不启用id作为查询条件，这就是传说中的动态查询&lt;/div&gt;&lt;img src="http://lonetear.com/aggbug.aspx?PostID=44" width="1" height="1"&gt;</content><author><name>cocoman</name><uri>http://lonetear.com/members/cocoman.aspx</uri></author><category term="数据库" scheme="http://lonetear.com/blogs/cocoman/archive/tags/_70656E63935E_/default.aspx" /></entry><entry><title>在win2003下安装delphi，dclite60.bpl无法加载错误</title><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/archive/2007/11/16/_2857_win2003_0B4E895BC588_delphi_0CFF_dclite60.bpl_E065D56CA0527D8F1995EF8B_.aspx" /><id>http://lonetear.com/blogs/cocoman/archive/2007/11/16/_2857_win2003_0B4E895BC588_delphi_0CFF_dclite60.bpl_E065D56CA0527D8F1995EF8B_.aspx</id><published>2007-11-16T14:25:00Z</published><updated>2007-11-16T14:25:00Z</updated><content type="html">正常安装delphi，没任何错误，如果启动delphi时出现dclite60.bpl或类似的组件加载错误。很有可能是DEP数据保护功能在作怪。 DEP数据保护功能是防止在数据内存块运行代码的保护措施。解决办法：我的电脑右键--属性--高级--性能--设置--数据执行保护或者关闭，或者将delphi32.exe加入排除列表&lt;img src="http://lonetear.com/aggbug.aspx?PostID=43" width="1" height="1"&gt;</content><author><name>cocoman</name><uri>http://lonetear.com/members/cocoman.aspx</uri></author><category term="Delphi" scheme="http://lonetear.com/blogs/cocoman/archive/tags/Delphi/default.aspx" /></entry><entry><title>SQL语句中使用条件表达式</title><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/archive/2007/11/16/SQL_ED8BE5532D4E7F4F28756167F64E6888BE8F0F5F_.aspx" /><id>http://lonetear.com/blogs/cocoman/archive/2007/11/16/SQL_ED8BE5532D4E7F4F28756167F64E6888BE8F0F5F_.aspx</id><published>2007-11-16T14:24:00Z</published><updated>2007-11-16T14:24:00Z</updated><content type="html">SELECT CASE WHEN b.dept is null THEN a.deptname ELSE b.dept END AS dept, CASE WHEN b.RepairCost is null THEN 0 ELSE b.RepairCost END AS Repair, CASE WHEN a.OilCost is null THEN 0 ELSE a.OilCost END AS Oil FROM table1 a, table2 b 另外一种方式 SELECT CASE dept WHEN &amp;#39;a&amp;#39; THEN &amp;#39;IT Department&amp;#39; WHEN &amp;#39;b&amp;#39; THEN &amp;#39;Finacial Department&amp;#39; ELSE &amp;#39;Unknown Dept&amp;#39; END as DeptName FROM .... 只适用于SQL SERVER，如果是ACCESS，则用IFF函数 IIf 函数 取决于表达式的计算结果，返回两部分之一。 语法 IIf(expr, truepart, falsepart) IIf 函数语法具有以下命名参数： 部分　　　　　　　　　　说明 expr　　　　　　必选。要计算的表达式。 truepart　　　　必选。在 expr 为 True 时返回的值或表达式。 falsepart　　　必选。在 expr 为 False 时返回的值或表达式。 说明 　　IIf总是同时计算truepart和falsepart，即使只返回这两者之一。因此，应注意意外的副作用。例如，如果计算falsepart会导至除以零的错误，则即使expr为True，也会发生错误。&lt;img src="http://lonetear.com/aggbug.aspx?PostID=41" width="1" height="1"&gt;</content><author><name>cocoman</name><uri>http://lonetear.com/members/cocoman.aspx</uri></author><category term="SQL" scheme="http://lonetear.com/blogs/cocoman/archive/tags/SQL/default.aspx" /></entry><entry><title>安装VS2005 sp1时如果出现&quot;无法使用此产品的安装源，请确认安装源存在并且你可以访问它”</title><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/archive/2007/11/16/_895BC588_VS2005-sp1_F66582599C67FA51B0732200E065D56C7F4F2875646BA74EC1548476895BC588906E0CFFF78B6E78A48B895BC588906E585B2857765E144E604FEF53E54EBF8BEE95835B1D20_.aspx" /><id>http://lonetear.com/blogs/cocoman/archive/2007/11/16/_895BC588_VS2005-sp1_F66582599C67FA51B0732200E065D56C7F4F2875646BA74EC1548476895BC588906E0CFFF78B6E78A48B895BC588906E585B2857765E144E604FEF53E54EBF8BEE95835B1D20_.aspx</id><published>2007-11-16T14:24:00Z</published><updated>2007-11-16T14:24:00Z</updated><content type="html">安装VS2005 sp1时如果出现&amp;ldquo;无法使用此产品的安装源，请确认安装源存在并且你可以访问它&amp;rdquo; 打开控制面板---管理工具，双击&amp;ldquo;本地安全设置&amp;rdquo;，打开&amp;ldquo;软件限制策略&amp;rdquo;，如果是空的，新建一个策略，然后双击&amp;ldquo;强制&amp;rdquo;，将第2个勾选由&amp;ldquo;所有用户&amp;rdquo;改为&amp;ldquo;除本地管理员以外的所有用户&amp;rdquo; 再安装即可。 &lt;img src="http://lonetear.com/aggbug.aspx?PostID=42" width="1" height="1"&gt;</content><author><name>cocoman</name><uri>http://lonetear.com/members/cocoman.aspx</uri></author><category term="Visual Studio" scheme="http://lonetear.com/blogs/cocoman/archive/tags/Visual+Studio/default.aspx" /></entry><entry><title>C#下操作ini文件的封装</title><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/archive/2007/11/16/C_23000B4ECD645C4F_ini_8765F64E8476015CC588_.aspx" /><id>http://lonetear.com/blogs/cocoman/archive/2007/11/16/C_23000B4ECD645C4F_ini_8765F64E8476015CC588_.aspx</id><published>2007-11-16T14:23:00Z</published><updated>2007-11-16T14:23:00Z</updated><content type="html">&lt;div&gt;由于微软非常鼓励programmers使用注册表来代替ini文件，在.NET FRAMEWORK里只有操作注册表的封装，却没有对操作ini文件进行封装。下面的代码填补了这一项空白，这是仿照DELPHI的TINIFILE类来改写的。&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;using System;&lt;br /&gt;using System.IO;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Collections;&lt;br /&gt;using System.Collections.Specialized;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;namespace Jerry.Huang&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;/// &amp;lt;summary&amp;gt;&lt;br /&gt;&amp;nbsp;/// 使用建议：虽然支持中文，但建议在ini文件中尽量避免使用中文，以避免在不同的操作系统产生不可预料的错误。&lt;br /&gt;&amp;nbsp;/// 1.7 修改了int、bool的读写&lt;br /&gt;&amp;nbsp;///&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;增加了DateTime和Double类型的读写&lt;br /&gt;&amp;nbsp;/// 原作者：陈省&amp;nbsp;修改：Jerry Huang&lt;br /&gt;&amp;nbsp;/// 原始版本来源：&lt;a href="http://hubdog.csdn.net/UpdateList/ul20030726.htm#Ini"&gt;&lt;font color="#ffffff"&gt;http://hubdog.csdn.net/UpdateList/ul20030726.htm#Ini&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;&amp;nbsp;/// 一个模仿Delphi的TIniFile的类&lt;br /&gt;&amp;nbsp;/// 修订：1.1 修正了对中文系统的支持。&lt;br /&gt;&amp;nbsp;/// 1.2 增加了UpdateFile方法,实现了对Win9x的支持&lt;br /&gt;&amp;nbsp;/// 1.3 增加了读写布尔，整数的操作&lt;br /&gt;&amp;nbsp;/// 1.4 修正了写Ini虽然成功，但是会抛出异常的错误&lt;br /&gt;&amp;nbsp;/// 1.5 ReadString返回的是Trim后的字符串&lt;br /&gt;&amp;nbsp;/// 1.6 统一并扩大了读写缓冲区的大小&lt;br /&gt;&amp;nbsp;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;&amp;nbsp;public class IniFile &lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;public string FileName; //INI文件名&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;//声明读写INI文件的API函数&lt;br /&gt;&amp;nbsp;&amp;nbsp;[DllImport(&amp;quot;kernel32&amp;quot;)]&lt;br /&gt;&amp;nbsp;&amp;nbsp;private static extern bool WritePrivateProfileString(string section,string key,string val,string filePath);&lt;br /&gt;&amp;nbsp;&amp;nbsp;[DllImport(&amp;quot;kernel32&amp;quot;)]&lt;br /&gt;&amp;nbsp;&amp;nbsp;private static extern int GetPrivateProfileString(string section,string key,string def, byte[] retVal,int size,string filePath);&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 构造函数。&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 当指定的INI文件不存在时可选是否建立或抛出异常。&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;IniFileName&amp;quot;&amp;gt;文件名&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;ForceCreate&amp;quot;&amp;gt;当文件不存在时是否建立&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public IniFile(string IniFileName, bool ForceCreate) &lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// 判断文件是否存在&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;FileInfo fileInfo=new FileInfo(IniFileName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Todo:搞清枚举的用法&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if ((!fileInfo.Exists)) //|| (FileAttributes.Directory in fileInfo.Attributes))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (!ForceCreate) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw(new ApplicationException(&amp;quot;Ini文件不存在&amp;quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fileInfo.Directory.Create();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fileInfo.Create();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//必须是完全路径，不能是相对路径&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;FileName = fileInfo.FullName;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;#region 各种数据类型的读写&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 将string型值写入ini。&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Section&amp;quot;&amp;gt;小节名&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Ident&amp;quot;&amp;gt;关键字&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Value&amp;quot;&amp;gt;要写入的值&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public void WriteString(string Section,string Ident,string Value) &lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (!WritePrivateProfileString(Section, Ident,Value,FileName))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// Todo:抛出自定义的异常&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw(new ApplicationException(&amp;quot;写Ini文件出错&amp;quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 从ini文件中读取string型值。&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 当读取失败时返回缺省值。&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Section&amp;quot;&amp;gt;小节名&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Ident&amp;quot;&amp;gt;关键字&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Default&amp;quot;&amp;gt;缺省值&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;returns&amp;gt;string型值&amp;lt;/returns&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public string ReadString(string Section,string Ident, string Default) &lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//StringBuilder Buffer = new StringBuilder(255);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Byte[] Buffer=new Byte[65535];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;int bufLen=GetPrivateProfileString(Section,Ident,Default,Buffer, Buffer.GetUpperBound(0),FileName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//必须设定0（系统默认的代码页）的编码方式，否则无法支持中文&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;string s=Encoding.GetEncoding(0).GetString(Buffer);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;s=s.Substring(0,bufLen);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return s.Trim();&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 从ini文件中读取int型值。&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 当读取失败时返回缺省值。&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Section&amp;quot;&amp;gt;小节名&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Ident&amp;quot;&amp;gt;关键字&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Default&amp;quot;&amp;gt;缺省值&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;returns&amp;gt;int型值&amp;lt;/returns&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public int ReadInteger(string Section, string Ident , int Default)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;string intStr=ReadString(Section, Ident, Default.ToString());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Convert.ToInt32(intStr);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;catch (Exception)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Console.WriteLine(ex.Message);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Default;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 将int型值写入ini&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Section&amp;quot;&amp;gt;小节名&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Ident&amp;quot;&amp;gt;关键字&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Value&amp;quot;&amp;gt;要写入的值&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public void WriteInteger(string Section,string Ident, int Value)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WriteString(Section, Ident, Value.ToString());&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 从ini文件中读取bool型值。&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 当读取失败时返回缺省值。&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Section&amp;quot;&amp;gt;小节名&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Ident&amp;quot;&amp;gt;关键字&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Default&amp;quot;&amp;gt;缺省值&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;returns&amp;gt;bool型值&amp;lt;/returns&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public bool ReadBool(string Section, string Ident, bool Default)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Convert.ToBoolean(ReadString(Section, Ident, Default.ToString() ));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;catch (Exception)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Console.WriteLine(ex.Message);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Default;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 将bool型值写入ini&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Section&amp;quot;&amp;gt;小节名&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Ident&amp;quot;&amp;gt;关键字&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Value&amp;quot;&amp;gt;要写入的值&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public void WriteBool(string Section, string Ident , bool Value)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WriteString(Section, Ident, Value.ToString());&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 将DateTime型值写入ini&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Section&amp;quot;&amp;gt;小节名&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Ident&amp;quot;&amp;gt;关键字&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Value&amp;quot;&amp;gt;要写入的值&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public void WriteDateTime(string Section, string Ident, DateTime Value)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WriteString(Section, Ident, Value.ToString());&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 从ini文件中读取DateTime型值。&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 当读取失败时返回缺省值。&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Section&amp;quot;&amp;gt;小节名&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Ident&amp;quot;&amp;gt;关键字&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Default&amp;quot;&amp;gt;缺省值&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;returns&amp;gt;DateTime型值&amp;lt;/returns&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public DateTime ReadDateTime(string Section, string Ident, DateTime Default)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Convert.ToDateTime(ReadString(Section, Ident, Default.ToString() ));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;catch (Exception)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Default;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;public void WriteDouble(string Section, string Ident, double Value)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WriteString(Section, Ident, Value.ToString());&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;public double ReadFloat(string Section, string Ident, double Default)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;try&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Convert.ToDouble(ReadString(Section, Ident, Default.ToString() ));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;catch (Exception)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Default;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;#endregion&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;//从Ini文件中，将指定的Section名称中的所有Ident添加到列表中&lt;br /&gt;&amp;nbsp;&amp;nbsp;public StringCollection ReadSection(string Section) &lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Byte[] Buffer=new Byte[16384];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;StringCollection Idents=new StringCollection();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Idents.Clear();&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;int bufLen=GetPrivateProfileString(Section, null, null, Buffer, Buffer.GetUpperBound(0),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FileName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//对Section进行解析&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;GetStringsFromBuffer(Buffer, bufLen, Idents);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Idents;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;private void GetStringsFromBuffer(Byte[] Buffer, int bufLen, StringCollection Strings) &lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Strings.Clear();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (bufLen!=0) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int start=0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for(int i=0; i &amp;lt; bufLen; i++) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if ((Buffer&lt;img src="http://cs.lonetear.com/emoticons/emotion-55.gif" alt="Idea" /&gt; == 0) &amp;amp;&amp;amp; ((i-start)&amp;gt;0)) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String s=Encoding.GetEncoding(0).GetString(Buffer, start, i-start);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Strings.Add(s);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;start=i+1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;//从Ini文件中，读取所有的Sections的名称&lt;br /&gt;&amp;nbsp;&amp;nbsp;public StringCollection ReadSections() &lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;StringCollection SectionList=new StringCollection();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Note:必须得用Bytes来实现，StringBuilder只能取到第一个Section&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;byte[] Buffer = new byte[65535];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;int bufLen=0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bufLen = GetPrivateProfileString(null, null, null,Buffer,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Buffer.GetUpperBound(0), FileName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;GetStringsFromBuffer(Buffer, bufLen, SectionList);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return SectionList;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;//读取指定的Section的所有Value到列表中&lt;br /&gt;&amp;nbsp;&amp;nbsp;public NameValueCollection ReadSectionValues(string Section) &lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;NameValueCollection Values=new NameValueCollection();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;StringCollection KeyList=ReadSection(Section);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Values.Clear();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach(string key in KeyList) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Values.Add(key, ReadString(Section, key, &amp;quot;&amp;quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Values;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;//清除某个Section&lt;br /&gt;&amp;nbsp;&amp;nbsp;public void EraseSection(string Section) &lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (!WritePrivateProfileString(Section, null, null, FileName)) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw(new ApplicationException(&amp;quot;无法清除Ini文件中的Section&amp;quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;//删除某个Section下的键&lt;br /&gt;&amp;nbsp;&amp;nbsp;public void DeleteKey(string Section, string Ident) &lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WritePrivateProfileString(Section, Ident, null, FileName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;//Note:对于Win9X，来说需要实现UpdateFile方法将缓冲中的数据写入文件&lt;br /&gt;&amp;nbsp;&amp;nbsp;//在Win NT, 2000和XP上，都是直接写文件，没有缓冲，所以，无须实现UpdateFile&lt;br /&gt;&amp;nbsp;&amp;nbsp;//执行完对Ini文件的修改之后，应该调用本方法更新缓冲区。&lt;br /&gt;&amp;nbsp;&amp;nbsp;public void UpdateFile() &lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;WritePrivateProfileString(null, null, null, FileName);&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 检查某个Section是否存在。&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Section&amp;quot;&amp;gt;小节名&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;returns&amp;gt;存在返回true，否则为false。&amp;lt;/returns&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public bool SectionExists(string Section)&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;StringCollection Sections=this.ReadSections();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Sections.IndexOf(Section)&amp;gt;-1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// 检查某个Section的某个键值是否存在。&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;/summary&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Section&amp;quot;&amp;gt;小节名&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;param name=&amp;quot;Ident&amp;quot;&amp;gt;关键字&amp;lt;/param&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;/// &amp;lt;returns&amp;gt;存在返回true，否则为false。&amp;lt;/returns&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;public bool ValueExists(string Section, string Ident) &lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;StringCollection Idents=ReadSection(Section);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return Idents.IndexOf(Ident)&amp;gt;-1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;//确保资源的释放&lt;br /&gt;&amp;nbsp;&amp;nbsp;~IniFile()&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;UpdateFile();&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;}&lt;br /&gt;}&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;img src="http://lonetear.com/aggbug.aspx?PostID=40" width="1" height="1"&gt;</content><author><name>cocoman</name><uri>http://lonetear.com/members/cocoman.aspx</uri></author><category term="C#" scheme="http://lonetear.com/blogs/cocoman/archive/tags/C_2300_/default.aspx" /></entry><entry><title>Delphi中调用.NET web service的参数问题</title><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/archive/2007/11/16/Delphi_2D4E038C28752E00_NET-web-service_8476C2537065EE959898_.aspx" /><id>http://lonetear.com/blogs/cocoman/archive/2007/11/16/Delphi_2D4E038C28752E00_NET-web-service_8476C2537065EE959898_.aspx</id><published>2007-11-16T14:21:00Z</published><updated>2007-11-16T14:21:00Z</updated><content type="html">&lt;div&gt;.NET 2.0写的web service发现无论如何，在delphi下都无法传递webmethod的参数，传入的值都是null。如果是用VS.NET 2003写的同样web service就没有问题。后来找到一篇比较有价值的文章，在WSDL import的文件service.pas的initialization段中加入一行：&lt;/div&gt;&lt;div&gt;&amp;nbsp; InvRegistry.RegisterInvokeOptions(TypeInfo(ServiceSoap), ioDocument);&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;即可解决问题。附文章网址及内容如下：&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;a href="http://www.community.borland.com/article/borcon/files/4132/paper/4132.html"&gt;&lt;u&gt;&lt;font color="#0000ff"&gt;http://www.community.borland.com/article/borcon/files/4132/paper/4132.html&lt;/font&gt;&lt;/u&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;RPC|Encoded vs. Document|Literal &lt;br /&gt;&lt;br /&gt;The biggest problem in interoperability is the fact that some servers use Document|Literal encoding, which most others use RPC|Encoded. Delphi servers only understand RPC|Encoded packages, but Delphi Clients can talk to both RPC|Encoded and Document|Literal servers. &lt;br /&gt;&lt;br /&gt;To communicate with a Doc|Lit server (Most .NET web services are doc|lit) you must set HTTPRio1.Converter.Options.soLiteralParams to true. This ensures that parameters encoded with &amp;quot;literal&amp;quot; are not unwound, which is necessary in doc|lit cases where a parameter name might be encapsulated under a sub tag under the XML element representing the function. &lt;br /&gt;&lt;br /&gt;In Delphi 7, Document encoding is supported in one way - you can make Delphi 7 client applications (consumers) for Document based webservices. What you cannot do is write Document based servers. If you&amp;#39;re writing a client for a document based server, you can import the WSDL and Delphi&amp;#39;s WSDL Importer will recognize that this is a document based server and generate necessary code for the conversion. FOr instance it will add the following call to the initialization section of your imported .pas file: &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;InvRegistry.RegisterInvokeOptions(TypeInfo(DataServiceSoap), ioDocument); &lt;br /&gt;&lt;br /&gt;This ensures that an Invoke call that uses the interface DataServiceSoap will be formatted using Document rules (not RPC). You can also use ioLiteral for doc-lit services. Using ioLiteral also ensures that your input and output types won&amp;#39;t be &amp;quot;unwound&amp;quot; - this needs some explanation. In RPC encoding, each method call is preceded by a method node in the XML datapacket. In Literal encoding, the method name is skipped and the parameters are unwound into XML. This and many small differences are actually handled directly by the Delphi SOAP runtime itself, so you don&amp;#39;t have to worry about them individually. But, use a proxy server to actually find out what&amp;#39;s happening behind the scenes in case there&amp;#39;s a problem.&lt;/div&gt;&lt;/div&gt;&lt;img src="http://lonetear.com/aggbug.aspx?PostID=39" width="1" height="1"&gt;</content><author><name>cocoman</name><uri>http://lonetear.com/members/cocoman.aspx</uri></author><category term="Delphi" scheme="http://lonetear.com/blogs/cocoman/archive/tags/Delphi/default.aspx" /></entry><entry><title>C#中的delegate和event</title><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/archive/2007/11/16/C_23002D4E8476_delegate_8C54_event.aspx" /><id>http://lonetear.com/blogs/cocoman/archive/2007/11/16/C_23002D4E8476_delegate_8C54_event.aspx</id><published>2007-11-16T14:19:00Z</published><updated>2007-11-16T14:19:00Z</updated><content type="html">&lt;span&gt;&amp;nbsp; &lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;在基于&lt;/span&gt;&lt;span&gt;Windows&lt;/span&gt;&lt;span&gt;平台的程序设计中，事件（&lt;/span&gt;&lt;span&gt;event&lt;/span&gt;&lt;span&gt;）是一个很重要的概念。因为在几乎所有的&lt;/span&gt;&lt;span&gt;Windows&lt;/span&gt;&lt;span&gt;应用程序中，都会涉及大量的异步调用，比如响应点击按钮、处理&lt;/span&gt;&lt;span&gt;Windows&lt;/span&gt;&lt;span&gt;系统消息等，这些异步调用都需要通过事件的方式来完成。即使在下一代开发平台&amp;mdash;&amp;mdash;&lt;/span&gt;&lt;span&gt;.NET&lt;/span&gt;&lt;span&gt;中也不例外。&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;那么什么是事件呢？所谓事件，就是由某个对象发出的消息，这个消息标志着某个特定的行为发生了，或者某个特定的条件成立了。比如用户点击了鼠标、&lt;/span&gt;&lt;span&gt;socket&lt;/span&gt;&lt;span&gt;上有数据到达等。那个触发（&lt;/span&gt;&lt;span&gt;raise&lt;/span&gt;&lt;span&gt;）事件的对象称为事件的发送者（&lt;/span&gt;&lt;span&gt;event sender&lt;/span&gt;&lt;span&gt;），捕获并响应事件的对象称为事件的接收者（&lt;/span&gt;&lt;span&gt;event receiver&lt;/span&gt;&lt;span&gt;）。&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;在这里，我们将要讨论的是，在&lt;/span&gt;&lt;span&gt;.NET&lt;/span&gt;&lt;span&gt;的主流开发语言&lt;/span&gt;&lt;span&gt;C#&lt;/span&gt;&lt;span&gt;中如何使用自定义的事件来实现我们自己的异步调用。&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;在&lt;/span&gt;&lt;span&gt;C#&lt;/span&gt;&lt;span&gt;中，事件的实现依赖于&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;，因此我们有必要先了解一下&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;的概念。&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="font-size:14pt;"&gt;&lt;font size="2"&gt;Delegate&lt;/font&gt;&lt;/span&gt;&lt;/strong&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;是&lt;/span&gt;&lt;span&gt;C#&lt;/span&gt;&lt;span&gt;中的一种类型，它实际上是一个能够持有对某个方法的引用的类。与其它的类不同，&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;类能够拥有一个签名（&lt;/span&gt;&lt;span&gt;signature，即函数说明，函数头，cocoman注&lt;/span&gt;&lt;span&gt;），并且它只能持有与它的签名相匹配的方法的引用（即参数个数/类型，和返回值完全一致，cocoman注）。它所实现的功能与&lt;/span&gt;&lt;span&gt;C/C++&lt;/span&gt;&lt;span&gt;中的函数指针十分相似。它允许你传递一个类&lt;/span&gt;&lt;span&gt;A&lt;/span&gt;&lt;span&gt;的方法&lt;/span&gt;&lt;span&gt;m&lt;/span&gt;&lt;span&gt;给另一个类&lt;/span&gt;&lt;span&gt;B&lt;/span&gt;&lt;span&gt;的对象，使得类&lt;/span&gt;&lt;span&gt;B&lt;/span&gt;&lt;span&gt;的对象能够调用这个方法&lt;/span&gt;&lt;span&gt;m&lt;/span&gt;&lt;span&gt;。但与函数指针相比，&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;有许多函数指针不具备的优点。首先，函数指针只能指向静态函数，而&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;既可以引用静态函数，又可以引用非静态成员函数。在引用非静态成员函数时，&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;不但保存了对此函数入口指针的引用，而且还保存了调用此函数的类实例的引用。其次，与函数指针相比，&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;是面向对象、类型安全、可靠的受控（&lt;/span&gt;&lt;span&gt;managed&lt;/span&gt;&lt;span&gt;）对象。也就是说，&lt;/span&gt;&lt;span&gt;runtime&lt;/span&gt;&lt;span&gt;能够保证&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;指向一个有效的方法，你无须担心&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;会指向无效地址或者越界地址。&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;实现一个&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;是很简单的，通过以下&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;个步骤即可实现一个&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;：&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;&lt;span&gt;1．&lt;span style="font:7pt 'Times New Roman';"&gt;&lt;font face="宋体"&gt;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;声明一个&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;对象，它应当与你想要传递的方法具有相同的参数和返回值类型。&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;&lt;span&gt;2．&lt;span style="font:7pt 'Times New Roman';"&gt;&lt;font face="宋体"&gt;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;创建&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;对象，并将你想要传递的函数作为参数传入。&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;&lt;span&gt;3．&lt;span style="font:7pt 'Times New Roman';"&gt;&lt;font face="宋体"&gt;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;在要实现异步调用的地方，通过上一步创建的对象来调用方法。&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;下面是一个简单的例子：&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;&lt;font size="2"&gt;using System;&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;&lt;font size="2"&gt;public class MyDelegateTest&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;&lt;font size="2"&gt;{&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// &lt;/span&gt;&lt;span&gt;步骤&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;，声明&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;对象&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;font size="2"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;public delegate void MyDelegate(string name);&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;// &lt;/span&gt;&lt;span&gt;这是我们欲传递的方法，它与&lt;/span&gt;&lt;span&gt;MyDelegate&lt;/span&gt;&lt;span&gt;具有相同的参数和返回值类型&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;font size="2"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;public static void MyDelegateFunc(string name)&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;font size="2"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;font size="2"&gt;&lt;span&gt;&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; &lt;/span&gt;Console.WriteLine(&amp;quot;Hello, {0}&amp;quot;, name);&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;font size="2"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &lt;/p&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;public static void &lt;/span&gt;&lt;span&gt;Main&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;font size="2"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;&lt;span&gt;&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; &lt;/span&gt;// &lt;/span&gt;&lt;span&gt;步骤&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;，创建&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;对象&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;font size="2"&gt;&lt;span&gt;&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; &lt;/span&gt;MyDelegate md = new MyDelegate(MyDelegateTest.MyDelegateFunc);&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;&lt;span&gt;&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; &lt;/span&gt;// &lt;/span&gt;&lt;span&gt;步骤&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;，调用&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;font size="2"&gt;&lt;span&gt;&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; &lt;/span&gt;md(&amp;quot;sam1111&amp;quot;);//这个调用，可以理解为md是一个特殊的object，一个装着函数的object。也就是为什么说delegate是&amp;ldquo;函数指针&amp;rdquo;的原因，cocoman注&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;font size="2"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;&lt;font size="2"&gt;}&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;输出结果是：&lt;/span&gt;&lt;span&gt;Hello, sam1111&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;p&gt;&lt;font color="#808080" size="2"&gt;cocoman附加comment&lt;/font&gt; &lt;/p&gt;&lt;p&gt;&lt;font color="#808080"&gt;&lt;font size="2"&gt;在google找到一篇blog说delegate实际上是java里的interface，但是该blog的评论中有反对的声音，据说老师曾在课堂上特意强调2者不同。依我来看，从上面的例子，可以看出delegate在效果上，的确是和interface很相似。public delegate void MyDelegate(string name);可以暂时看作事先定义的interface，而其后的MyDelegateFunc函数可以看作前面delegate对象的实现。&lt;/font&gt;&lt;font size="2"&gt;所以，可以用interface的概念去帮助理解上面的例子。但是在理论层次上，我不建议将delegate和interface划等号。&lt;/font&gt;&lt;/font&gt; &lt;/p&gt;&lt;p&gt;&lt;font color="#808080" size="2"&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;了解了&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;，下面我们来看看，在&lt;/span&gt;&lt;span&gt;C#&lt;/span&gt;&lt;span&gt;中对事件是如何处理的。&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;strong&gt;&lt;span style="font-size:14pt;"&gt;在&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="font-size:14pt;"&gt;C#&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="font-size:14pt;"&gt;中处理事件&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="font-size:14pt;"&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;C#&lt;/span&gt;&lt;span&gt;中的事件处理实际上是一种具有特殊签名（signature）的&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;，象下面这个样子：&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;&lt;font size="2"&gt;public delegate void MyEventHandler(object sender, MyEventArgs e);&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;其中的两个参数，&lt;/span&gt;&lt;span&gt;sender&lt;/span&gt;&lt;span&gt;代表事件发送者，&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;是事件参数类。&lt;/span&gt;&lt;span&gt;MyEventArgs&lt;/span&gt;&lt;span&gt;类用来包含与事件相关的数据，所有的事件参数类都必须从&lt;/span&gt;&lt;span&gt;System.EventArgs&lt;/span&gt;&lt;span&gt;类派生。当然，如果你的事件不含参数，那么可以直接用&lt;/span&gt;&lt;span&gt;System.EventArgs&lt;/span&gt;&lt;span&gt;类作为参数。&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;就是这么简单，结合&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;的实现，我们可以将自定义事件的实现归结为以下几步：&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;&lt;span&gt;1．&lt;span style="font:7pt 'Times New Roman';"&gt;&lt;font face="宋体"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;定义&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;对象类型，它有两个参数，第一个参数是事件发送者对象，第二个参数是事件参数类对象。&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;&lt;span&gt;2．&lt;span style="font:7pt 'Times New Roman';"&gt;&lt;font face="宋体"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;定义事件参数类，此类应当从&lt;/span&gt;&lt;span&gt;System.EventArgs&lt;/span&gt;&lt;span&gt;类派生。如果事件不带参数，这一步可以省略。&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;&lt;span&gt;3．&lt;span style="font:7pt 'Times New Roman';"&gt;&lt;font face="宋体"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;定义事件处理方法，它应当与&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;对象具有相同的参数和返回值类型。&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;&lt;span&gt;4．&lt;span style="font:7pt 'Times New Roman';"&gt;&lt;font face="宋体"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;用&lt;/span&gt;&lt;span&gt;event&lt;/span&gt;&lt;span&gt;关键字定义事件对象，它同时也是一个&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;对象。&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;&lt;span&gt;5．&lt;span style="font:7pt 'Times New Roman';"&gt;&lt;font face="宋体"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;用&lt;/span&gt;&lt;span&gt;+=&lt;/span&gt;&lt;span&gt;操作符添加事件到事件队列中（&lt;/span&gt;&lt;span&gt;-=&lt;/span&gt;&lt;span&gt;操作符能够将事件从队列中删除）。&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;&lt;span&gt;6．&lt;span style="font:7pt 'Times New Roman';"&gt;&lt;font face="宋体"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;在需要触发事件的地方用调用&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;的方式写事件触发方法。一般来说，此方法应为&lt;/span&gt;&lt;span&gt;protected&lt;/span&gt;&lt;span&gt;访问限制，即不能以&lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt;方式调用，但可以被子类继承。名字是&lt;/span&gt;&lt;span&gt;On&lt;em&gt;EventName&lt;/em&gt;&lt;/span&gt;&lt;span&gt;。（原文中的此步骤过于繁琐，下面的代码已经采用该文评论中的简化版本，cocoman注）&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;font size="2"&gt;&lt;span&gt;&lt;span&gt;7．&lt;span style="font:7pt 'Times New Roman';"&gt;&lt;font face="宋体"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;在适当的地方调用事件触发方法触发事件。&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;下面是一个简单的例子：&lt;/span&gt;&lt;span&gt;&lt;/span&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;using&amp;nbsp;System;&lt;br /&gt;&lt;br /&gt;public&amp;nbsp;class&amp;nbsp;EventTest&lt;br /&gt;{&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span&gt;// &lt;span&gt;步骤&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;，定义&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;对象&lt;/span&gt;&lt;br /&gt;public&amp;nbsp;delegate&amp;nbsp;void&amp;nbsp;MyEventHandler(object&amp;nbsp;sender,System.EventArgs&amp;nbsp;e);&lt;br /&gt;//步骤2省略&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;p&gt;&lt;span&gt;// &lt;/span&gt;&lt;span&gt;步骤&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;，定义事件处理方法，它与&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;对象具有相同的参数和返回值类&lt;/span&gt;&lt;span&gt;型&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;public&amp;nbsp;static&amp;nbsp;void&amp;nbsp;MyEventFunc(object&amp;nbsp;sender,System.EventArgs&amp;nbsp;e)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&amp;quot;My&amp;nbsp;Event&amp;nbsp;is&amp;nbsp;done!&amp;quot;);&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;p&gt;// &lt;span&gt;步骤&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;，用&lt;/span&gt;&lt;span&gt;event&lt;/span&gt;&lt;span&gt;关键字定义事件对象&lt;/span&gt;&lt;br /&gt;private&amp;nbsp;event&amp;nbsp;MyEventHandler&amp;nbsp;myevent;&lt;br /&gt;&lt;br /&gt;public&amp;nbsp;EventTest()&lt;br /&gt;{ &lt;/p&gt;&lt;p&gt;// &lt;span&gt;步骤&lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;，用&lt;/span&gt;&lt;span&gt;+=&lt;/span&gt;&lt;span&gt;操作符将事件添加到队列中&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.myevent+=new&amp;nbsp;MyEventHandler(MyEventFunc);&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;font face="Tahoma"&gt;// &lt;/font&gt;&lt;span&gt;步骤&lt;/span&gt;&lt;span&gt;7&lt;/span&gt;&lt;span&gt;，触发事件&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;public&amp;nbsp;void&amp;nbsp;RaiseEvent()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EventArgs&amp;nbsp;e=new&amp;nbsp;EventArgs();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(myevent!=null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; myevent(this,e);// &lt;span&gt;步骤&lt;/span&gt;&lt;span&gt;6&lt;/span&gt;&lt;span&gt;，以调用&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;的方式写事件触发函数&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public&amp;nbsp;static&amp;nbsp;void&amp;nbsp;Main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; EventTest&amp;nbsp;et=new&amp;nbsp;EventTest();&lt;br /&gt;&amp;nbsp;&amp;nbsp; Console.WriteLine(&amp;quot;Please&amp;nbsp;input&amp;nbsp;a&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp; if(Console.ReadLine()==&amp;quot;a&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; et.RaiseEvent();&lt;br /&gt;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(&amp;quot;Error&amp;quot;);&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;p&gt;} &lt;/p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;// &lt;/span&gt;&lt;span&gt;步骤&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;，定义事件处理方法，它与&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;对象具有相同的参数和返回值类&lt;/span&gt;&lt;span&gt;型&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;public&amp;nbsp;static&amp;nbsp;void&amp;nbsp;MyEventFunc(object&amp;nbsp;sender,System.EventArgs&amp;nbsp;e)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&amp;quot;My&amp;nbsp;Event&amp;nbsp;is&amp;nbsp;done!&amp;quot;);&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;p&gt;// &lt;span&gt;步骤&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;，用&lt;/span&gt;&lt;span&gt;event&lt;/span&gt;&lt;span&gt;关键字定义事件对象&lt;/span&gt;&lt;br /&gt;private&amp;nbsp;event&amp;nbsp;MyEventHandler&amp;nbsp;myevent;&lt;br /&gt;&lt;br /&gt;public&amp;nbsp;EventTest()&lt;br /&gt;{ &lt;/p&gt;&lt;p&gt;// &lt;span&gt;步骤&lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;，用&lt;/span&gt;&lt;span&gt;+=&lt;/span&gt;&lt;span&gt;操作符将事件添加到队列中&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.myevent+=new&amp;nbsp;MyEventHandler(MyEventFunc);&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;font face="Tahoma"&gt;// &lt;/font&gt;&lt;span&gt;步骤&lt;/span&gt;&lt;span&gt;7&lt;/span&gt;&lt;span&gt;，触发事件&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;public&amp;nbsp;void&amp;nbsp;RaiseEvent()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EventArgs&amp;nbsp;e=new&amp;nbsp;EventArgs();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(myevent!=null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; myevent(this,e);// &lt;span&gt;步骤&lt;/span&gt;&lt;span&gt;6&lt;/span&gt;&lt;span&gt;，以调用&lt;/span&gt;&lt;span&gt;delegate&lt;/span&gt;&lt;span&gt;的方式写事件触发函数&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public&amp;nbsp;static&amp;nbsp;void&amp;nbsp;Main()&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; EventTest&amp;nbsp;et=new&amp;nbsp;EventTest();&lt;br /&gt;&amp;nbsp;&amp;nbsp; Console.WriteLine(&amp;quot;Please&amp;nbsp;input&amp;nbsp;a&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp; if(Console.ReadLine()==&amp;quot;a&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; et.RaiseEvent();&lt;br /&gt;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(&amp;quot;Error&amp;quot;);&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;p&gt;} &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;输出结果如下，黑体为用户的输入：&lt;/span&gt;&lt;span&gt;&lt;/span&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;Please input &amp;lsquo;a&amp;rsquo;: &lt;strong&gt;a&lt;/strong&gt;&lt;/span&gt; &lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;span&gt;My event is done!&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;img src="http://lonetear.com/aggbug.aspx?PostID=38" width="1" height="1"&gt;</content><author><name>cocoman</name><uri>http://lonetear.com/members/cocoman.aspx</uri></author><category term="C#" scheme="http://lonetear.com/blogs/cocoman/archive/tags/C_2300_/default.aspx" /></entry><entry><title>C#中操作XML</title><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/archive/2007/11/16/C_23002D4ECD645C4F_XML.aspx" /><id>http://lonetear.com/blogs/cocoman/archive/2007/11/16/C_23002D4ECD645C4F_XML.aspx</id><published>2007-11-16T14:18:00Z</published><updated>2007-11-16T14:18:00Z</updated><content type="html">&lt;div&gt;创建XML文件有2种方法&lt;/div&gt;&lt;div&gt;方法一：&lt;/div&gt;&lt;div&gt;XmlDocument xmldoc ;//整个xml文档对象&lt;br /&gt;XmlNode xmlnode ;//节点对象&lt;br /&gt;XmlElement xmlelem ;//节点下的元素&lt;/div&gt;&lt;div&gt;xmldoc = new XmlDocument ( ) ;&lt;br /&gt;//加入XML的声明段落&lt;br /&gt;xmlnode = xmldoc.CreateNode ( XmlNodeType.XmlDeclaration , &amp;quot;&amp;quot; , &amp;quot;&amp;quot; ) ;&lt;br /&gt;xmldoc.AppendChild ( xmlnode ) ;&lt;br /&gt;//加入一个根节点&lt;br /&gt;xmlelem = xmldoc.CreateElement ( &amp;quot;&amp;quot; , &amp;quot;bookstore&amp;quot; , &amp;quot;&amp;quot; ) ;&lt;br /&gt;xmldoc.AppendChild ( xmlelem ) ;&lt;br /&gt;//加入子节点&lt;/div&gt;&lt;div&gt;&lt;p&gt;XmlNode root=xmldoc.SelectSingleNode(&amp;quot;bookstore&amp;quot;);//查找&amp;lt;bookstore&amp;gt; 根节点&lt;br /&gt;XmlElement xe1=xmldoc.CreateElement(&amp;quot;book&amp;quot;);//创建一个&amp;lt;book&amp;gt;节点 &lt;br /&gt;xe1.SetAttribute(&amp;quot;genre&amp;quot;,&amp;quot;fantasy&amp;quot;);//设置该节点genre属性 &lt;br /&gt;xe1.SetAttribute(&amp;quot;ISBN&amp;quot;,&amp;quot;2-3631-4&amp;quot;);//设置该节点ISBN属性 &lt;/p&gt;&lt;p&gt;XmlElement xesub1=xmldoc.CreateElement(&amp;quot;title&amp;quot;); &lt;br /&gt;xesub1.InnerText=&amp;quot;Oberon&amp;#39;s Legacy&amp;quot;;&lt;br /&gt;xe1.AppendChild(xesub1);//添加到&amp;lt;book&amp;gt;节点中 &lt;br /&gt;XmlElement xesub2=xmldoc.CreateElement(&amp;quot;author&amp;quot;); &lt;br /&gt;xesub2.InnerText=&amp;quot;Corets, Eva&amp;quot;; &lt;br /&gt;xe1.AppendChild(xesub2);//添加到&amp;lt;book&amp;gt;节点中 &lt;br /&gt;XmlElement xesub3=xmldoc.CreateElement(&amp;quot;price&amp;quot;); &lt;br /&gt;xesub3.InnerText=&amp;quot;5.95&amp;quot;; &lt;br /&gt;xe1.AppendChild(xesub3); &lt;/p&gt;&lt;p&gt;root.AppendChild(xe1);//添加到&amp;lt;bookstore&amp;gt;节点中 &lt;br /&gt;//保存创建好的XML文档&lt;br /&gt;xmldoc.Save ( Server.MapPath(&amp;quot;data.xml&amp;quot;) ) ; &lt;/p&gt;&lt;p&gt;方法二： &lt;/p&gt;&lt;p&gt;&amp;nbsp; XmlTextWriter xmlWriter;&lt;br /&gt;&amp;nbsp;&amp;nbsp;string strFilename = Server.MapPath(&amp;quot;data1.xml&amp;quot;) ; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;xmlWriter = new XmlTextWriter(strFilename,Encoding.Default);//创建一个xml文档&lt;br /&gt;&amp;nbsp;&amp;nbsp;xmlWriter.Formatting = Formatting.Indented;&lt;br /&gt;&amp;nbsp;&amp;nbsp;xmlWriter.WriteStartDocument();&lt;br /&gt;&amp;nbsp;&amp;nbsp;xmlWriter.WriteStartElement(&amp;quot;bookstore&amp;quot;); &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;xmlWriter.WriteStartElement(&amp;quot;book&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;xmlWriter.WriteAttributeString(&amp;quot;genre&amp;quot;,&amp;quot;fantasy&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;xmlWriter.WriteAttributeString(&amp;quot;ISBN&amp;quot;,&amp;quot;2-3631-4&amp;quot;); &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;xmlWriter.WriteStartElement(&amp;quot;title&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;xmlWriter.WriteString(&amp;quot;Oberon&amp;#39;s Legacy&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;xmlWriter.WriteEndElement(); &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;xmlWriter.WriteStartElement(&amp;quot;author&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;xmlWriter.WriteString(&amp;quot;Corets, Eva&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;xmlWriter.WriteEndElement(); &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;xmlWriter.WriteStartElement(&amp;quot;price&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;xmlWriter.WriteString(&amp;quot;5.95&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;xmlWriter.WriteEndElement(); &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;xmlWriter.WriteEndElement(); &lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;xmlWriter.Close();&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;以上2种方法均在脚本所在目录生成data.xml如下&lt;/div&gt;&lt;div&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;gb2312&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;bookstore&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;book genre=&amp;quot;fantasy&amp;quot; ISBN=&amp;quot;2-3631-4&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;Oberon&amp;#39;s Legacy&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;author&amp;gt;Corets, Eva&amp;lt;/author&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;price&amp;gt;5.95&amp;lt;/price&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/book&amp;gt;&lt;br /&gt;&amp;lt;/bookstore&amp;gt;&lt;br /&gt;&amp;nbsp;////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;1、往&amp;lt;bookstore&amp;gt;节点中插入一个&amp;lt;book&amp;gt;节点：&lt;br /&gt;&amp;nbsp;&amp;nbsp; XmlDocument xmlDoc=new XmlDocument();&lt;br /&gt;&amp;nbsp;&amp;nbsp; xmlDoc.Load(&amp;quot;bookstore.xml&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp; XmlNode root=xmlDoc.SelectSingleNode(&amp;quot;bookstore&amp;quot;);//查找&amp;lt;bookstore&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; XmlElement xe1=xmlDoc.CreateElement(&amp;quot;book&amp;quot;);//创建一个&amp;lt;book&amp;gt;节点&lt;br /&gt;&amp;nbsp;&amp;nbsp; xe1.SetAttribute(&amp;quot;genre&amp;quot;,&amp;quot;李赞红&amp;quot;);//设置该节点genre属性&lt;br /&gt;&amp;nbsp;&amp;nbsp; xe1.SetAttribute(&amp;quot;ISBN&amp;quot;,&amp;quot;2-3631-4&amp;quot;);//设置该节点ISBN属性&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp; XmlElement xesub1=xmlDoc.CreateElement(&amp;quot;title&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp; xesub1.InnerText=&amp;quot;CS从入门到精通&amp;quot;;//设置文本节点&lt;br /&gt;&amp;nbsp;&amp;nbsp; xe1.AppendChild(xesub1);//添加到&amp;lt;book&amp;gt;节点中&lt;br /&gt;&amp;nbsp;&amp;nbsp; XmlElement xesub2=xmlDoc.CreateElement(&amp;quot;author&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp; xesub2.InnerText=&amp;quot;候捷&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp; xe1.AppendChild(xesub2);&lt;br /&gt;&amp;nbsp;&amp;nbsp; XmlElement xesub3=xmlDoc.CreateElement(&amp;quot;price&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp; xesub3.InnerText=&amp;quot;58.3&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp; xe1.AppendChild(xesub3);&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp; root.AppendChild(xe1);//添加到&amp;lt;bookstore&amp;gt;节点中&lt;br /&gt;&amp;nbsp;&amp;nbsp; xmlDoc.Save(&amp;quot;bookstore.xml&amp;quot;);&lt;br /&gt;//===============================================&lt;br /&gt;结果为：&lt;br /&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;gb2312&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;bookstore&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;book genre=&amp;quot;fantasy&amp;quot; ISBN=&amp;quot;2-3631-4&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;Oberon&amp;#39;s Legacy&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;author&amp;gt;Corets, Eva&amp;lt;/author&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;price&amp;gt;5.95&amp;lt;/price&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/book&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;book genre=&amp;quot;李赞红&amp;quot; ISBN=&amp;quot;2-3631-4&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;CS从入门到精通&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;author&amp;gt;候捷&amp;lt;/author&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;price&amp;gt;58.3&amp;lt;/price&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/book&amp;gt;&lt;br /&gt;&amp;lt;/bookstore&amp;gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;2、修改节点：将genre属性值为&amp;ldquo;李赞红&amp;ldquo;的节点的genre值改为&amp;ldquo;update李赞红&amp;rdquo;，将该节点的子节点&amp;lt;author&amp;gt;的文本修改为&amp;ldquo;亚胜&amp;rdquo;。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; XmlNodeList nodeList=xmlDoc.SelectSingleNode(&amp;quot;bookstore&amp;quot;).ChildNodes;//获取bookstore节点的所有子节点&lt;br /&gt;&amp;nbsp;&amp;nbsp; foreach(XmlNode xn in nodeList)//遍历所有子节点&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; XmlElement xe=(XmlElement)xn;//将子节点类型转换为XmlElement类型&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(xe.GetAttribute(&amp;quot;genre&amp;quot;)==&amp;quot;李赞红&amp;quot;)//如果genre属性值为&amp;ldquo;李赞红&amp;rdquo;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xe.SetAttribute(&amp;quot;genre&amp;quot;,&amp;quot;update李赞红&amp;quot;);//则修改该属性为&amp;ldquo;update李赞红&amp;rdquo;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; XmlNodeList nls=xe.ChildNodes;//继续获取xe子节点的所有子节点&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach(XmlNode xn1 in nls)//遍历&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; XmlElement xe2=(XmlElement)xn1;//转换类型&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(xe2.Name==&amp;quot;author&amp;quot;)//如果找到&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xe2.InnerText=&amp;quot;亚胜&amp;quot;;//则修改&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;//找到退出来就可以了&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp; xmlDoc.Save(&amp;quot;bookstore.xml&amp;quot;);//保存。&lt;br /&gt;//==================================================&lt;br /&gt;最后结果为：&lt;br /&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;gb2312&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;bookstore&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;book genre=&amp;quot;fantasy&amp;quot; ISBN=&amp;quot;2-3631-4&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;Oberon&amp;#39;s Legacy&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;author&amp;gt;Corets, Eva&amp;lt;/author&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;price&amp;gt;5.95&amp;lt;/price&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/book&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;book genre=&amp;quot;update李赞红&amp;quot; ISBN=&amp;quot;2-3631-4&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;CS从入门到精通&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;author&amp;gt;亚胜&amp;lt;/author&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;price&amp;gt;58.3&amp;lt;/price&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/book&amp;gt;&lt;br /&gt;&amp;lt;/bookstore&amp;gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;3、删除 &amp;lt;book genre=&amp;quot;fantasy&amp;quot; ISBN=&amp;quot;2-3631-4&amp;quot;&amp;gt;节点的genre属性，删除 &amp;lt;book genre=&amp;quot;update李赞红&amp;quot; ISBN=&amp;quot;2-3631-4&amp;quot;&amp;gt;节点。&lt;br /&gt;XmlNodeList xnl=xmlDoc.SelectSingleNode(&amp;quot;bookstore&amp;quot;).ChildNodes;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp; foreach(XmlNode xn in xnl)&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; XmlElement xe=(XmlElement)xn;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(xe.GetAttribute(&amp;quot;genre&amp;quot;)==&amp;quot;fantasy&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xe.RemoveAttribute(&amp;quot;genre&amp;quot;);//删除genre属性&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if(xe.GetAttribute(&amp;quot;genre&amp;quot;)==&amp;quot;update李赞红&amp;quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xe.RemoveAll();//删除该节点的全部内容&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; xmlDoc.Save(&amp;quot;bookstore.xml&amp;quot;);&lt;br /&gt;//===========================================&lt;br /&gt;最后结果为：&lt;br /&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;gb2312&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;bookstore&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;book ISBN=&amp;quot;2-3631-4&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;title&amp;gt;Oberon&amp;#39;s Legacy&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;author&amp;gt;Corets, Eva&amp;lt;/author&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;price&amp;gt;5.95&amp;lt;/price&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/book&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;book&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/book&amp;gt;&lt;br /&gt;&amp;lt;/bookstore&amp;gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;4、显示所有数据。&lt;br /&gt;&amp;nbsp;&amp;nbsp; XmlNode xn=xmlDoc.SelectSingleNode(&amp;quot;bookstore&amp;quot;);&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp; XmlNodeList xnl=xn.ChildNodes;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp; foreach(XmlNode xnf in xnl)&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; XmlElement xe=(XmlElement)xnf;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(xe.GetAttribute(&amp;quot;genre&amp;quot;));//显示属性值&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(xe.GetAttribute(&amp;quot;ISBN&amp;quot;));&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; XmlNodeList xnf1=xe.ChildNodes;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach(XmlNode xn2 in xnf1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(xn2.InnerText);//显示子节点点文本&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; } &lt;/div&gt;&lt;img src="http://lonetear.com/aggbug.aspx?PostID=37" width="1" height="1"&gt;</content><author><name>cocoman</name><uri>http://lonetear.com/members/cocoman.aspx</uri></author><category term="C#" scheme="http://lonetear.com/blogs/cocoman/archive/tags/C_2300_/default.aspx" /></entry><entry><title>漫谈多线程下载</title><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/archive/2007/11/16/_2B6F088C1A59BF7E0B7A0B4E7D8F_.aspx" /><id>http://lonetear.com/blogs/cocoman/archive/2007/11/16/_2B6F088C1A59BF7E0B7A0B4E7D8F_.aspx</id><published>2007-11-16T14:14:00Z</published><updated>2007-11-16T14:14:00Z</updated><content type="html">&lt;div&gt;&lt;font color="#ff0000" size="3"&gt;&lt;strong&gt;cocoman原创。转载请注明出处，谢谢！&lt;/strong&gt;&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;本文所指的多线程下载是指基于windows下的多线程下载同一个文件。这项技术的难点，主要集中在以下几个方面：&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;font size="3"&gt;1）多个线程读写同一文件&lt;/font&gt;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;在一个下载任务里面，各个下载点是独立的线程，从远程的文件服务器上读取文件，然后写入本地文件。从多线程的概念上来看，各个下载点是相互独立的（虽然在CPU时间上他们仍是按顺序写入本地文件），所以存在着一个很关键的问题：多个线程操作同一个文件。这在文件操作上是不允许的。一个文件在打开之后，其他程序和线程是禁止向这个文件进行操作。特别是写操作（读操作有共享打开模式）。&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;在这里要引入一个变通的方案：File Mapping（文件映射）。文件映射是指将物理硬盘上的一个文件，映射成虚拟内存。要使用文件映射有3个主要的步骤：第1是建立File mapping object（FMO），第2步是在FMO上建立File View（FV）。第3是释放映射，在这一步操作系统会处理善后工作。例如将虚拟内存中的所有改变写入文件中，这点就完全不需要我们关心而由操作系统负责（这也是API的精髓所在）。这3个步骤分别用到3个windows API函数：CreateFileMapping，MapViewOfFile以及UnmapViewOfFile。建立FMO就是将硬盘上的文件，映射成一个FMO；建立file view就是将FMO映射成虚拟内存中的一段地址（可以映射整个FMO的view，也可以仅仅映射部分FMO的view）。&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;将物理文件映射成虚拟内存以后，对文件的操作，实际上就变成了在内存的操作。所以在各个下载点写文件的时候，实际上是在file view上进行写操作（将读回来的流，copy到&amp;ldquo;内存&amp;rdquo;中的某一地址）&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;在建立部分file view的时候，有一个细节问题。就是当只映射FMO一部分的时候，映射的起始点，并不是任意的。比如文件的大小是10000字节，我要从0开始映射第1个file view，然后从5000开始映射第2个file view。第1个file view从0开始，没有问题，但第2个从5000开始，则有可能会失败。这是因为内存操作都是一块一块来的，不同的操作系统，块的大小是不一样的，windows NT内核的系统（NT,XP,2003)的块的大小是64K（65536）。那么，第2个file view的起点地址，必须是64K的整数倍（即只能从65536，65536&amp;times;2，65536&amp;times;3&amp;hellip;&amp;hellip;开始）。一般来说，在映射部分FMO的时候，先要利用另外一个API函数GetSystemInfo获得数据类型为SYSTEM_INFO的一个结构变量，该变量中的dwAllocationGranularity域包含了该大小的值。&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;font size="3"&gt;2）动态文件映射&lt;/font&gt;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;如果你的程序支持在下载的过程中动态建立新的下载点，那么就需要考虑动态文件映射的问题了。在上一个问题上，假设我们要将文件分成2个线程下载。那么在建立file view的时候，就是将文件的全半部分映射成一个file view，后半部分映射为另一个file view。这种映射file view的方式我称之为&amp;ldquo;静态映射&amp;rdquo;。静态映射的最大问题是映射的文件大小被固定了，这就意味着下载的过程只能由这2个下载点进行下载，而不能够在下载过程中添加新的下载点。我想到的一个解决方案是采用&amp;ldquo;动态映射&amp;rdquo;，就是说，在下载开始之前，根据远程文件的filesize，将文件分成N个小块，在下载的时候，先映射第1个小块为file view，下载完当前小块后，释放映射，接着向母线程请求&lt;strong&gt;相邻&lt;/strong&gt;的下一个小块，然后再映射，再下载，依此类推，直到相邻的下一个小块是已经下载完成的，这就意味着这一个下载点的任务已经完成。for exaple，一个文件被分成10个小块（一般情况下，块数的多少是由dwAllocationGranularity的值决定的，而不像本例中假设为10），那么线程1（下载点1）从block1开始映射、下载，线程2（下载点2）则从block6开始，当线程1下载完block5的时候，发现block6已经下载过了，那么线程1的任务就完成了，同样地，线程2下载到block10的时候，已经没有block了，线程2的任务也完成了。&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;上一段的&amp;ldquo;相邻&amp;rdquo;我用了粗体，这是因为，基本上所有的下载协议（HTTP,FTP,MMS等）都是TCP连接，TCP连接都是必须先&amp;ldquo;握手&amp;rdquo;再传输数据。如果不是相邻的话，那么远程的下载起始点就不是当前点的next byte，这就需要重新&amp;ldquo;握手&amp;rdquo;，浪费时间。&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;这个动态映射的好处就是，比如说，当线程1下载到block2，线程2下载到block8的时候，用户嫌下载太慢了，要再添加一个下载点&amp;mdash;&amp;mdash;线程3，那么线程3就会由母线程产生，并由block4开始下载，那么线程3下载到block5的时候就停止了，而原来的线程1下载完block3的时候，就完成任务了。从而实现了动态建立下载点。&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;font size="3"&gt;总结&lt;/font&gt;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;以上的下载方式，都是建立在一个基础上：远程文件的filesize已知。如果由于某些原因（例如下载的是媒体流文件，文件大小不能在建立连接的时候获知），无法事先获得文件的filesize，那么这个文件就不支持多线程下载了，而只能单线程下载。这也是不少下载软件中经常出现的提示之一：&amp;ldquo;该文件大小未知，不能启用多线程&amp;rdquo;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;以上的2点，第1点已经写出实际的代码，实践并顺利通过。第2点尚未写出实际代码，仅理论上的推理。&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font size="3"&gt;此外，文中所提到的各种API函数仅仅是为读者提供线索，详细的用法读者需要进一步进行搜索，google上能找到很多资料。所以在此并不重复。&lt;/font&gt;&lt;/div&gt;&lt;img src="http://lonetear.com/aggbug.aspx?PostID=36" width="1" height="1"&gt;</content><author><name>cocoman</name><uri>http://lonetear.com/members/cocoman.aspx</uri></author><category term="多线程" scheme="http://lonetear.com/blogs/cocoman/archive/tags/_1A59BF7E0B7A_/default.aspx" /></entry><entry><title>cache in rmiregistry?</title><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/archive/2007/11/16/cache-in-rmiregistry_3F00_.aspx" /><id>http://lonetear.com/blogs/cocoman/archive/2007/11/16/cache-in-rmiregistry_3F00_.aspx</id><published>2007-11-16T14:04:00Z</published><updated>2007-11-16T14:04:00Z</updated><content type="html">&lt;div&gt;Recently I am writing a chatroom project with Java RMI. And I found something strange, dangerous, stupid..... as well as a lot of bugs in Jbuilder9. BTW, seems Jbuilder only suitable for some normal application. It&amp;#39;s not very excited&amp;nbsp; even a nightmare while doing something need to combine java application and web server.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Rmiregistry seemingly has some caching mechanism. If I make some mistake deliberately (e.g. delete a&amp;nbsp;necessary class file)&amp;nbsp;in the first running, correct it and then run again, you will find the previous error appear again. However, if you kill the rmiregistry process (or reboot the system if you want),&amp;nbsp;make everthing start&amp;nbsp;again, you can see everything goes smoothly.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;As a result, everytime after&amp;nbsp;I recompile the source code, I will stop the rmiregistry and start it again. Just to make sure nothing has been cached. Silly, eh?&lt;/div&gt;&lt;img src="http://lonetear.com/aggbug.aspx?PostID=35" width="1" height="1"&gt;</content><author><name>cocoman</name><uri>http://lonetear.com/members/cocoman.aspx</uri></author><category term="Java" scheme="http://lonetear.com/blogs/cocoman/archive/tags/Java/default.aspx" /></entry><entry><title>serverSocket with multi-thread</title><link rel="alternate" type="text/html" href="http://lonetear.com/blogs/cocoman/archive/2007/11/16/serverSocket-with-multi_2D00_thread.aspx" /><id>http://lonetear.com/blogs/cocoman/archive/2007/11/16/serverSocket-with-multi_2D00_thread.aspx</id><published>2007-11-16T13:56:00Z</published><updated>2007-11-16T13:56:00Z</updated><content type="html">&lt;div&gt;Here is some important summaries about socket object and multi-thread programming in Java.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;font color="#ff0000"&gt;Main Step:&lt;/font&gt;&lt;/div&gt;&lt;div&gt;1) Create a subclass(EchoServer.java) of Thread(or implement the &lt;font color="#000000" size="2"&gt;Runnable interface&lt;/font&gt;)&amp;nbsp;to deal with the clients.&lt;/div&gt;&lt;div&gt;2) In the main method, assign a ServerSocket to listen on a specific port(9998 for example)&lt;/div&gt;&lt;div&gt;3) when there is a request, accept it and return a clientSocket&lt;/div&gt;&lt;div&gt;4) Pass the clientSocket into a new Thread, and then start it&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;font color="#ff0000"&gt;Code Fragments:&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font color="#000000"&gt;&lt;strong&gt;within the EchoServer.java&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font color="#808000"&gt;public class EchoServer extends Thread&lt;br /&gt;{&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font color="#808000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Socket clientSocket;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static boolean shutDownServer;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public EchoServer(Socket s) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clientSocket=s;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font color="#808000"&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font color="#808000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void run()&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; boolean finished=false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(!finished) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; finished=deal_with_client(clientSocket);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }catch(Exception e){}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clientSocket.close();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }catch(Exception e){}&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font color="#808000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font color="#808000"&gt;&amp;nbsp; ...other method omitted.....&lt;br /&gt;}&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font color="#808000"&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font color="#000000"&gt;&lt;strong&gt;the main method&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;int server_port=9998;&lt;/div&gt;&lt;div&gt;&lt;font color="#333300"&gt;ServerSocket rServer;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font color="#333300"&gt;Socket request;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;Thread receiveThread; &lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rServer=new ServerSocket(server_port);&lt;font color="#993300"&gt;//create the serverSocket to listen&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; boolean done=false;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(!done){&lt;br /&gt;&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; request=rServer.accept();&lt;font color="#993300"&gt;//when there is a request, accept it and return a clientSocket&lt;br /&gt;&lt;/font&gt;&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; System.out.println(&amp;quot;Incoming client...&amp;quot;);&lt;br /&gt;&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; System.out.println(&amp;quot;IP: &amp;quot;+request.getInetAddress().getHostAddress());&lt;br /&gt;&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; System.out.println(&amp;quot;Port: &amp;quot;+request.getPort());&lt;br /&gt;&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; System.out.println(&amp;quot;##########&amp;quot;);&lt;br /&gt;&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; receiveThread=new EchoServer(request);&lt;font color="#993300"&gt;//create a new Thread, pass the clientSocket into it&lt;/font&gt;&lt;br /&gt;&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; receiveThread.start();&lt;font color="#993300"&gt;//start the Thread&lt;/font&gt;&lt;br /&gt;&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; if (EchoServer.shutDownServer) done=true;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }catch(IOException e){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(e.getMessage());&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;img src="http://lonetear.com/aggbug.aspx?PostID=33" width="1" height="1"&gt;</content><author><name>cocoman</name><uri>http://lonetear.com/members/cocoman.aspx</uri></author><category term="Java" scheme="http://lonetear.com/blogs/cocoman/archive/tags/Java/default.aspx" /></entry></feed>