<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_梁利锋</title><subtitle type="text"/><id>http://feed.cnblogs.com/blog/u/60359/rss</id><updated>2011-12-28T14:13:19Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/60359/rss"/><entry><id>http://www.cnblogs.com/lephone/archive/2011/12/28/dbentry4_1.html</id><title type="text">DbEntry.Net 4.1</title><summary type="text">这是我设计的一个轻量级的 .Net ORM (Object Relational Mapping) 数据访问及 WEB 框架。对于 ORM 和 Sql 调用，它都拥有清晰和易用的接口，目前支持 SqlServer、SQLite、MySql、Access、Firebird、PostgreSQL、Oracle 等数据库。对于 WEB 开发，它既支持 ASP.NET 2.0 的 DataSource 方式，也支持 Ruby On Rails 风格的 MVC 方式。支持 Linq 方式的查询，也提供一个简单的 IoC。 目前，数据库部分已经支持多主键、多表联合查询、快速分页、隐式数据库事务、连贯...</summary><published>2011-12-28T14:13:00Z</published><updated>2011-12-28T14:13:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2011/12/28/dbentry4_1.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2011/12/28/dbentry4_1.html"/><content type="html">&lt;p&gt;这是我设计的一个轻量级的 .Net ORM (Object Relational Mapping) 数据访问及 WEB 框架。对于 ORM 和 Sql 调用，它都拥有清晰和易用的接口，目前支持 SqlServer、SQLite、MySql、Access、Firebird、PostgreSQL、Oracle 等数据库。对于 WEB 开发，它既支持 ASP.NET 2.0 的 DataSource 方式，也支持 Ruby On Rails 风格的 MVC 方式。支持 Linq 方式的查询，也提供一个简单的 IoC。&lt;br /&gt;&lt;br /&gt;　　目前，数据库部分已经支持多主键、多表联合查询、快速分页、隐式数据库事务、连贯API查 询、ActiveRecord风格查询、动态对象、部分保存、自动创建数据表、一对一、一对多、多对多关系等功能，具体实现请参阅 Samples 中的例子程序和单元测试的内容。&lt;br /&gt;&lt;br /&gt;　　而 DataSource 部分，因为绑定数据访问组件，所以可以只需要修改配置文件，不需要修改任何代码的在不同的数据之间切换。另外，还支持按命名约定的方式绑定&amp;ldquo;新建&amp;rdquo;和&amp;ldquo;编辑&amp;rdquo;页面的控件，以最少的代码完成输入、验证、保存等一系列操作。&lt;br /&gt;&lt;br /&gt;　　Rails 风格的 MVC 框架目前已经完成 MVC 部分，脚手架，基类中的 LinkTo、UrlTo 等快捷函数，Http Get 支持等。目前脚手架部分没有数据验证模块，不过，自己写的 MVC 代码可以自行实现验证。&lt;br /&gt;&lt;br /&gt;　 　这个版本中，例子程序访问的数据库主要是 Access，而单元测试使用的数据库是 SQLite，通过修改配置文件中数据源部分，可以使之不需要重新编译即可工作于其它数据库上。配置部分通过 App.config 进行，请参阅 Samples 中的例子程序中的 App.config 和 UnitTest 项目内嵌的配置文件 UnitTest.config.xml 。所有例子程序在 MS Sql Server 2005 Express、MS Sql Server 2008 Express、 MS Access 2003、MySql 5.0、SQLite 3、Firebird 2.1.0, PostgreSQL 8.3.3 和 Oracle 10g Express 上测试过。&lt;br /&gt;&lt;br /&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/83760/2011052422171998.png" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;　　v4.1 版主要的改变为：&lt;br /&gt;　　&amp;middot;增加 QueryRequired 功能；&lt;br /&gt;　　&amp;middot;更严格的编译时检查；&lt;br /&gt;　　&amp;middot;Model 增加可覆盖的 OnInserting、OnUpdating、OnDeleting；&lt;br /&gt;　　&amp;middot;重新整理 DbEntryDataSource 的事件；&lt;br /&gt;　　&amp;middot;增加 ConditionBuilder；&lt;br /&gt;　　&amp;middot;增加 NotIn 支持；&lt;br /&gt;　　&amp;middot;增加 LoadRelation 函数；&lt;br /&gt;　　&amp;middot;Bug 修正 ；&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;　　下载本组件和浏览文档请访问 &lt;a href="http://www.codeplex.com/DbEntry/" target="_blank"&gt;http://www.codeplex.com/DbEntry/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lephone/aggbug/2305432.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lephone/archive/2011/12/28/dbentry4_1.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2011/05/24/dbentry4_0.html</id><title type="text">DbEntry.Net 4.0</title><summary type="text">这是我设计的一个轻量级的 .Net ORM (Object Relational Mapping) 数据访问及 WEB 框架。对于 ORM 和 Sql 调用，它都拥有清晰和易用的接口，目前支持 SqlServer、SQLite、MySql、Access、Firebird、PostgreSQL、Oracle 等数据库。对于 WEB 开发，它既支持 ASP.NET 2.0 的 DataSource 方式，也支持 Ruby On Rails 风格的 MVC 方式。支持 Linq 方式的查询，也提供一个简单的 IoC。 目前，数据库部分已经支持多主键、多表联合查询、快速分页、隐式数据库事务、连贯AP.</summary><published>2011-05-24T14:22:00Z</published><updated>2011-05-24T14:22:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2011/05/24/dbentry4_0.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2011/05/24/dbentry4_0.html"/><content type="html">&lt;p&gt;这是我设计的一个轻量级的 .Net ORM (Object Relational Mapping) 数据访问及 WEB 框架。对于 ORM 和 Sql 调用，它都拥有清晰和易用的接口，目前支持 SqlServer、SQLite、MySql、Access、Firebird、PostgreSQL、Oracle 等数据库。对于 WEB 开发，它既支持 ASP.NET 2.0 的 DataSource 方式，也支持 Ruby On Rails 风格的 MVC 方式。支持 Linq 方式的查询，也提供一个简单的 IoC。&lt;br /&gt;&lt;br /&gt;　　目前，数据库部分已经支持多主键、多表联合查询、快速分页、隐式数据库事务、连贯API查询、ActiveRecord风格查询、动态对象、部分保存、自动创建数据表、一对一、一对多、多对多关系等功能，具体实现请参阅 Samples 中的例子程序和单元测试的内容。&lt;br /&gt;&lt;br /&gt;　　而 DataSource 部分，因为绑定数据访问组件，所以可以只需要修改配置文件，不需要修改任何代码的在不同的数据之间切换。另外，还支持按命名约定的方式绑定&amp;ldquo;新建&amp;rdquo;和&amp;ldquo;编辑&amp;rdquo;页面的控件，以最少的代码完成输入、验证、保存等一系列操作。&lt;br /&gt;&lt;br /&gt;　　Rails 风格的 MVC 框架目前已经完成 MVC 部分，脚手架，基类中的 LinkTo、UrlTo 等快捷函数，Http Get 支持等。目前脚手架部分没有数据验证模块，不过，自己写的 MVC 代码可以自行实现验证。&lt;br /&gt;&lt;br /&gt;　　这个版本中，例子程序访问的数据库主要是 Access，而单元测试使用的数据库是 SQLite，通过修改配置文件中数据源部分，可以使之不需要重新编译即可工作于其它数据库上。配置部分通过 App.config 进行，请参阅 Samples 中的例子程序中的 App.config 和 UnitTest 项目内嵌的配置文件 UnitTest.config.xml 。所有例子程序在 MS Sql Server 2005 Express、MS Sql Server 2008 Express、 MS Access 2003、MySql 5.0、SQLite 3、Firebird 2.1.0, PostgreSQL 8.3.3 和 Oracle 10g Express 上测试过。&lt;br /&gt;&lt;br /&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/83760/2011052422171998.png" /&gt;&lt;br /&gt;&lt;br /&gt;　　v4.0 版主要的改变为：&lt;br /&gt;　　&amp;middot;更新到 .Net 4.0；&lt;br /&gt;　　&amp;middot;支持使用动态对象返回结果集；&lt;br /&gt;　　&amp;middot;改为不使用 abstract 的方式；&lt;br /&gt;　　&amp;middot;不使用内存程序集，而是直接修改程序集；&lt;br /&gt;　　&amp;middot;对于 Model 使用的 DbContext 改为使用属性定义；&lt;br /&gt;　　&amp;middot;增加对于 ComposedOf 的支持；&lt;br /&gt;　　&amp;middot;结构调整，Bug 修改等；&lt;br /&gt;&lt;br /&gt;　　下载本组件和浏览文档请访问 &lt;a target="_blank" href="http://www.codeplex.com/DbEntry/"&gt;http://www.codeplex.com/DbEntry/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lephone/aggbug/2056046.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lephone/archive/2011/05/24/dbentry4_0.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/12/23/analyze_simple_script_engine.html</id><title type="text">《点睛简单脚本引擎》源代码导读 —— 原型、命令模式应用</title><summary type="text">这篇文章，是2004年写的，本来没准备再重发，今天因为一些事，翻了出来，鉴于现在仍然有很多人停留在YY工厂模式和单件模式上，另外，我觉得这篇文章和所涉及的代码写的还是挺不错的，所以重发出来，个人觉得，还是有意义的。　　前几天，和朋友谈论《点睛简单脚本引擎》的代码，发现，其实还是需要讲解一下，特别是说明为什么这种方式比直观的代码编写更好。　　脚本本身的格式比较简单，所有的参数用“|”分隔，第一个参数是命令名，如果命令名为空，则此行被视为“注释”。　　从类图来看代码结构就非常清晰了，其中，黄色的类是“静态类”，也就是只包含一些静态函数的类；而粉色的类是“自定义异常”；青色的类是“接口”；淡绿色的类</summary><published>2010-12-23T05:40:00Z</published><updated>2010-12-23T05:40:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/12/23/analyze_simple_script_engine.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/12/23/analyze_simple_script_engine.html"/><content type="html">&lt;p&gt;&lt;em&gt;这篇文章，是2004年写的，本来没准备再重发，今天因为一些事，翻了出来，鉴于现在仍然有很多人停留在YY工厂模式和单件模式上，另外，我觉得这篇文章和所涉及的代码写的还是挺不错的，所以重发出来，个人觉得，还是有意义的。&lt;/em&gt;&lt;/p&gt;&#xD;
&lt;p&gt;前几天，和朋友谈论《点睛简单脚本引擎》的代码，发现，其实还是需要讲解一下，特别是说明为什么这种方式比直观的代码编写更好。&lt;/p&gt;&#xD;
&lt;p&gt;脚本本身的格式比较简单，所有的参数用&amp;ldquo;|&amp;rdquo;分隔，第一个参数是命令名，如果命令名为空，则此行被视为&amp;ldquo;注释&amp;rdquo;。&lt;/p&gt;&#xD;
&lt;p&gt;从类图来看代码结构就非常清晰了，其中，黄色的类是&amp;ldquo;静态类&amp;rdquo;，也就是只包含一些静态函数的类；而粉色的类是&amp;ldquo;自定义异常&amp;rdquo;；青色的类是&amp;ldquo;接口&amp;rdquo;；淡绿色的类是普通的类。我们先来看一下类图：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2010/83760/2010122313272847.gif" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;其中，ApplicationEntry 是程序的入口点，其中的 Main 函数创建一个 ProcessorControlCenter 的实例，并且执行它的 RunScript 函数。而 ProcessorControlCenter 中的 RunScript 函数也很简单，只是使用了 ProcessorFactory 创建出一个 CallScriptProcessor，并且执行它的 DoProcessor 函数。&lt;/p&gt;&#xD;
&lt;p&gt;最基本的接口是一个 IProcessor 接口，包含一个 DoProcess 函数，然后 IProcessorInstance 继承了 IProcessor，包含一个 CreateInstance 函数。其目的在于，IProcessor 接口定义出每一个 Processor 都要执行的操作，而 IProcessorInstance 则是为了让 ProcessorFactory 能够简单的创建出&amp;ldquo;处理器&amp;rdquo;。&lt;/p&gt;&#xD;
&lt;p&gt;从 IProcessor 来理解，就非常简单、直观了。比如 CopyFileProcessor，和脚本中的&amp;ldquo;CopyFile | 源文件 | 目标文件 | [是否覆盖 = true]&amp;rdquo;相对应，所以，它包含三个属性：SourceFileName、TargetFileName 和 OverWrite。在它的构造函数中，根据传入的参数字符串数组，分析出那三个属性各自应该是什么，如果参数有错误，则抛出异常，而在 DoProcess 函数中，根据这三个参数，执行文件复制工作。&lt;/p&gt;&#xD;
&lt;p&gt;其它的 Processor 都大同小异，不过，比较特殊的是 CallScriptProcessor。这一个 Processor 的特殊之处在于，它要读出整个脚本，并通过 ProcessorFactory 创建出相应的 Processor，并且插入它的 _ProcessorList 集合这个属性之中。在 DoProcess 函数中，它执行一个简单的遍历，顺序执行 _ProcessorList 集合中所有的 Processor 的 DoProcess 函数。&lt;/p&gt;&#xD;
&lt;p&gt;所以，在程序运行后，首先创建出一个 CallScriptProcessor，它的 _ProcessorList 集合包含所有这个脚本中的 Processor，而如果这些 Processor 中又有 CallScriptProcessor，则这个 CallScriptProcessor 的 _ProcessorList 又包含子脚本中的 Processor，形成一个树结构，顺序遍历这颗树，并且执行其中的 DoProcess 函数，就会执行整个脚本链。这样，每一个 Processor 各司其职，把它们整合在一起后就正确的执行并得到了我们希望的结果。&lt;/p&gt;&#xD;
&lt;p&gt;ProcessorFactory 包含一个 CreateProcessorByScriptLine 函数，它通过一个脚本行创建一个相应的 Processor。这个函数对这个脚本行用&amp;ldquo;|&amp;rdquo;分割，根据分割后的字符串数组的第一个字符串，决定创建哪一个 Processor。这个创建的过程被通过 IProcessorInstance 接口的 CreateInstance 函数分配给了各个 Processor，所以 CreateInstance 应该使用 new 来产生一个自己的实例。&lt;/p&gt;&#xD;
&lt;p&gt;比较特殊的一点是，各个 Processor 的带参数的构造函数的访问符都是 private，这是为了防止在复制其它 Processor 代码以创建新的 Processor 的时候，忘了修改 CreateInstance 而造成错误。当其访问符是 private 的时候，如果忘了修改 CreateInstance 的话，将会产生一个编译错误，提醒我们应该修改它。&lt;/p&gt;&#xD;
&lt;p&gt;在 ProcessorFactory 初始化的时候，通过一个 Hashtable 把脚本命令和 Processor 形成一一对应的关系，在 CreateProcessorByScriptLine 中就只要使用这个 Hashtable 就可以创建 Processor，而不必使用冗长而不易维护的 switch 语句了。&lt;/p&gt;&#xD;
&lt;p&gt;而在第二版中，主要是增加了自定义属性 ActiveProcessorAttribute，它接受一个字符串作为 Processor 对应的脚本命令名。而在 ProcessorFactory 中，使用反射取得这个模块中所有的类，并且检查，如果某一个类是从 IProcessor 接口继承，而且定义了 ActiveProcessorAttribute 属性的话，就会被加入 Hashtable，而在 CreateProcessorByScriptLine，通过反射找到这个类的构造函数，并且使用 Invoke 调用这个构造函数，完成 Processor 的创建。这样，ProcessorFactory 在增加新的 Processor 的情况下，不需要有任何修改，而 Processor 本身，也消除了对于 CreateInstance 和无参数的构造函数的需求，变得更加简单、清晰，而 IProcessorInstance 接口也不需要了。。&lt;/p&gt;&#xD;
&lt;p&gt;为什么说这种方法比直观的代码编写方法好呢？我们来看看一个直观的代码是怎么解决这个问题，并且对应于代码的演化，直观的代码和这种使用一个统一的接口的方式之间的差别。&lt;/p&gt;&#xD;
&lt;p&gt;从直观的角度讲，我们的程序应该读取这个脚本，并且执行相应的操作，一个 switch 结构应该是第一个对于此类实现的想法：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ApplicationEntry&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Main(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; [] args)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( args &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; args.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;        {&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( FileStream f &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileStream(args[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;]) )&lt;br /&gt;            {&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; s;&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( (s &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; f.ReadLine()) &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;                {&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( s.Trim() &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;                    {&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss[] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s.Split(&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;|&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( ss &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;                        {&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;switch&lt;/span&gt;&lt;span style="color: #000000;"&gt;( ss[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToLower() )&lt;br /&gt;                            {&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt;: &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 是注释&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;                                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;copyfile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                                    DoCopyFile(ss);&lt;br /&gt;                                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;deletefile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                                    DoDeleteFile(ss);&lt;br /&gt;                                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                            }&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;以上代码中没有展示 DoCopyFile 之类的函数，这些函数需要在内部解析 ss，并且执行相应的操作，在只有简单的操作，而且只有少量的指令的时候也还算可以理解，不过，增加了 CallScript 之后，就有些困难，需要进行重构了：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ApplicationEntry&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Main(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; [] args)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( args &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; args.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;        {&lt;br /&gt;            ProcessFile(args[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;]);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ProcessFile(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileName)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( FileStream f &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileStream(FileName) )&lt;br /&gt;        {&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; s;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( (s &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; f.ReadLine()) &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;            {&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( s.Trim() &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;                {&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss[] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s.Split(&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;|&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( ss &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;                    {&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;switch&lt;/span&gt;&lt;span style="color: #000000;"&gt;( ss[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToLower() )&lt;br /&gt;                        {&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt;: &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 是注释&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;copyfile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                                DoCopyFile(ss);&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;deletefile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                                DoDeleteFile(ss);&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;callscript&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                                DoCallScript(ss);&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    DoCallScript(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] ss)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( ss.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;        {&lt;br /&gt;            ProcessFile(ss[&lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;br /&gt;　　这样，这种 switch 结构使用递归调用的方法，虽然有些结构混乱，也实现了 CallScript。不过，在设计 SimpleScript 引擎的时候，有对于 Script 中的参数错误的提示的要求：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2010/83760/2010122313275234.gif" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;一开始，我是把 CallScript 的 ReadToEnd( _TargetFileName ) 放在 DoProcess() 函数中的，这样，如果当前脚本出错，就会出现错误提示：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; DoProcess()&lt;br /&gt;{&lt;br /&gt;    ReadToEnd( _TargetFileName );&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( IProcessor ip &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; _ProcessorList )&lt;br /&gt;    {&lt;br /&gt;        ip.DoProcess();&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;br /&gt;　　不过，后来我觉得，这种脚本错误是应该在执行任何一个指令前进行的检查，即使对于子脚本中的错误，也应该在所有脚本执行之前提示，所以修改代码，把 ReadToEnd( _TargetFileName ) 移动到 CallScript 的构造函数中，就完成了这个任务：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; CallScriptProcessor(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; [] Params)&lt;br /&gt;{&lt;br /&gt;    _ProcessorList &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Collections.ArrayList();&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;switch&lt;/span&gt;&lt;span style="color: #000000;"&gt;( Params.Length )&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;            _TargetFileName &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; IOHelper.GetFullPath( Params[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;] );&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; ParseParamErrorException();&lt;br /&gt;    }&lt;br /&gt;    ReadToEnd( _TargetFileName );&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;br /&gt;　　现在，我们来考虑一下上面的 switch 结构的程序要实现这种类型的脚本错误检查的话，需要进行哪些修改呢？因为在 switch 结构的程序中，脚本行的解析和执行是在同一个地方进行的，所以首先应该把它们进行拆分，不过，如果把 DoCopyFile 拆分成两个函数，那么解析函数解析出的参数怎么传递给执行函数？也许应该建立一个 CopyFile_SourceFile 和 CopyFile_TargetFile 吧。抛开参数传递的问题，如果已经把以前的 DoCopyFile 函数都拆分成了解析函数和执行函数两部分，为了实现执行前脚本参数检查，应该怎么修改程序的结构呢？恐怕还是需要一个解析用的 switch 语句组吧：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ProcessScriptParam(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileName)&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( FileStream f &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileStream(FileName) )&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; s;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( (s &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; f.ReadLine()) &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;        {&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( s.Trim() &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;            {&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss[] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s.Split(&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;|&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( ss &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;                {&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;switch&lt;/span&gt;&lt;span style="color: #000000;"&gt;( ss[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToLower() )&lt;br /&gt;                    {&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt;: &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 是注释&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;copyfile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            ParseCopyFileParam(ss);&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;deletefile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            ParseDoDeleteFileParam(ss);&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;callscript&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            ParseDoCallScriptParam(ss);&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ProcessFile(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileName)&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( FileStream f &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileStream(FileName) )&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; s;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( (s &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; f.ReadLine()) &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;        {&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( s.Trim() &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;            {&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss[] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; s.Split(&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;|&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ( ss &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ss.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;br /&gt;                {&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;switch&lt;/span&gt;&lt;span style="color: #000000;"&gt;( ss[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToLower() )&lt;br /&gt;                    {&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt;: &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 是注释&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;copyfile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            ParseCopyFileParam(ss);&lt;br /&gt;                            ProcessCopyFile(ss);&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;deletefile&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            ParseDoDeleteFileParam(ss);&lt;br /&gt;                            ProcessDeleteFile(ss);&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;callscript&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            ParseDoCallScriptParam(ss);&lt;br /&gt;                            ProcessCallScript(ss);&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;br /&gt;　　现在，switch 结构的程序已经变成了这种庞大而难于维护的样子，如果要增加一个新的操作，就更加困难了，除了要实现相应的解析执行函数之外，还要维护这两个庞大的 switch 结构，出错的可能性也大大增加了。而相对的，我写的 SimpleScript 的代码，任何时候新增一个操作，都是同样的简单&amp;hellip;&amp;hellip;&lt;/p&gt;&#xD;
&lt;p&gt;当然，对于 Processor 的结构来说，我使用的是命令（Command）模式，而对于 Processor 的创建来说，我使用的是原型（Prototype）模式。不过，在设计中，我并没有，其实也不太清楚我使用了哪种模式，只是在多种想法中进行选择，对代码进行重构，最终得到了我认为最好的结构 &amp;mdash;&amp;mdash; 而这种结构正好符合了某些设计模式。现在看来，反而是这种自行发现模式的情况，更有利于对于设计模式有更深的认识。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;源代码下载：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://llf.hanzify.org/studio/article/show/326" target="_blank"&gt;点睛简单脚本引擎 第一版&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://llf.hanzify.org/studio/article/show/328" target="_blank"&gt;点睛简单脚本引擎 第二版&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lephone/aggbug/1914751.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lephone/archive/2010/12/23/analyze_simple_script_engine.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/11/19/a_database_optimize_operation.html</id><title type="text">数据库操作优化一例</title><summary type="text">数据库升级，需要对几个表进行一些数据转换，具体是这样：针对每一个 Item，从 orders 表里查出 Shop_Id，并把此 Id 赋值给 items 和 skus 中的 Shop_Id。下面是最初实现的代码，其中 LargerResultProcessor 是一个基类，负责遍历泛型参数 T 所指向的数据库表，并以每页 100 项的方式分页，并对每一项调用 ProcessItem 函数，而子类只...</summary><published>2010-11-19T07:23:00Z</published><updated>2010-11-19T07:23:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/11/19/a_database_optimize_operation.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/11/19/a_database_optimize_operation.html"/><content type="html">&lt;p&gt;数据库升级，需要对几个表进行一些数据转换，具体是这样：针对每一个 Item，从 orders 表里查出 Shop_Id，并把此 Id 赋值给 items 和 skus 中的 Shop_Id。下面是最初实现的代码，其中 LargerResultProcessor 是一个基类，负责遍历泛型参数 T 所指向的数据库表，并以每页 100 项的方式分页，并对每一项调用 ProcessItem 函数，而子类只需实现 ProcessItem 函数即可：&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('17aead26-1ed2-42ba-9c53-425b1d61353a')"&gt;&#xD;
&lt;div id="cnblogs_code_open_17aead26-1ed2-42ba-9c53-425b1d61353a"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ItemRenameCompanyId : LargerResultProcessor&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Item&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ProcessItem(Item item)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; template1 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;@"&lt;/span&gt;&lt;span style="color: #800000;"&gt;select top 1 shop_id from orders where Item_id = '{0}'&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;        var sql1 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Format(template1, item.Id);&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; template2 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;@"&lt;/span&gt;&lt;span style="color: #800000;"&gt;update Items set shop_id={0} where id = {1};&lt;br /&gt;                                   update skus set shop_id={0} where item_id = {1};&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        {&lt;br /&gt;            var obj &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; DbEntry.Context.ExecuteScalar(sql1);&lt;br /&gt;            var sql2 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Format(template2, &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;long&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Parse(obj.ToString()), item.Id);&lt;br /&gt;            DbEntry.Context.ExecuteNonQuery(sql2);&lt;br /&gt;        }&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt;&lt;span style="color: #000000;"&gt; (Exception exception)&lt;br /&gt;        {&lt;br /&gt;            Logger.Default.Warn(exception &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; item.Id.ToString());&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;上面这段代码，逻辑比较简单，针对每一项，使用 Select 语句取出 Shop_Id，并且执行 Update，只是有个问题，就是执行速度比较慢，对于我们 6 万左右 Item，4 万左右 Sku，99 万左右 Order 的表，需要执行约 40 分钟，才能转换完毕。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这些代码，虽然是一次性操作，但是对于运行系统，停机时间越短越好，于是进行一些优化工作，数据库对于大量重复的语句，如果使用参数的方式，因为可以避免对于语句的重复解析工作，所以速度会快一些，按照这个思路，简单的修改如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('aa59287f-379b-4717-8dab-e0d3d34304fd')"&gt;&#xD;
&lt;div id="cnblogs_code_open_aa59287f-379b-4717-8dab-e0d3d34304fd"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ItemRenameCompanyId : LargerResultProcessor&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Item&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ProcessItem(Item item)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; template1 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;@"&lt;/span&gt;&lt;span style="color: #800000;"&gt;select top 1 shop_id from orders where Item_id = @id&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; template2 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;@"&lt;/span&gt;&lt;span style="color: #800000;"&gt;update Items set shop_id=@sid where id = @id;&lt;br /&gt;update skus set shop_id=@sid where item_id = @id;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        {&lt;br /&gt;            var sql1 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; SqlStatement(template1, &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DataParameter(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;@id&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, item.Id));&lt;br /&gt;            var sid &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Convert.ToInt64(DbEntry.Context.ExecuteScalar(sql1));&lt;br /&gt;            var sql2 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; SqlStatement(template2, &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DataParameter(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;@sid&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, sid), &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DataParameter(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;@id&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, item.Id));&lt;br /&gt;            DbEntry.Context.ExecuteNonQuery(sql2);&lt;br /&gt;        }&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt;&lt;span style="color: #000000;"&gt; (Exception exception)&lt;br /&gt;        {&lt;br /&gt;            Logger.Default.Warn(exception &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; item.Id.ToString());&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;测试这个程序，大概 25 分钟可以完成转换。有一些提高，不过，我们真正要修改的数据量并不大，一共只有 6 万 加 4 万 大约 10 万条数据，所以 25 分钟还是有些长了。简单分析后，Orders 是最大的表，如果整体速度慢，则导致速度慢最大的可能因素，应该是查询 Orders，所以稍换一个思路，提前把 Item_Id 和 Shop_Id 的对应关系查找出来，放到内存里，从而避免每次 ProcessItem 都要进行 Orders 表的查询。至于内存里的数据，本来准备用 Dictionary 的，后来一想，Id 都是 long 型的数据，而且不能算&amp;ldquo;稀疏&amp;rdquo;矩阵，基本可以称为&amp;ldquo;稠密&amp;rdquo;矩阵，所以，直接用数组应该是速度更快，所以先查询出 Items 的最大 Id，用于设置数组大小，再按索引赋值即可：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('a9281afe-4a56-4d9d-aa02-8866cacfa7b3')"&gt;&#xD;
&lt;div id="cnblogs_code_open_a9281afe-4a56-4d9d-aa02-8866cacfa7b3"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ItemRenameCompanyId : LargerResultProcessor&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Item&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;readonly&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;long&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] _dic;&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; ItemRenameCompanyId()&lt;br /&gt;    {&lt;br /&gt;        var count &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Convert.ToInt64(DbEntry.Context.ExecuteScalar(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;select top 1 Id from items order by id desc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;)) &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;br /&gt;        _dic &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;long&lt;/span&gt;&lt;span style="color: #000000;"&gt;[count];&lt;br /&gt;&lt;br /&gt;        var sql &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; SqlStatement(&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;select items.id as xiid,orders.shop_id as xsid from items inner join orders on orders.item_id = items.id group by items.id,orders.shop_id&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;                {SqlTimeOut &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;300&lt;/span&gt;&lt;span style="color: #000000;"&gt;};&lt;br /&gt;&lt;br /&gt;        dynamic list &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; DbEntry.Context.ExecuteDynamicList(sql);&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt;(dynamic row &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; list)&lt;br /&gt;        {&lt;br /&gt;            _dic[row.xiid] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; row.xsid;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;protected&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;override&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ProcessItem(Item item)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; template2 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;@"&lt;/span&gt;&lt;span style="color: #800000;"&gt;update Items set shop_id=@sid where id = @id;&lt;br /&gt;update skus set shop_id=@sid where item_id = @id;&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;        {&lt;br /&gt;            var sid &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; _dic[item.Id];&lt;br /&gt;            var sql2 &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; SqlStatement(template2, &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DataParameter(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;@sid&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, sid), &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DataParameter(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;@id&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, item.Id));&lt;br /&gt;            DbEntry.Context.ExecuteNonQuery(sql2);&lt;br /&gt;        }&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt;&lt;span style="color: #000000;"&gt; (Exception exception)&lt;br /&gt;        {&lt;br /&gt;            Logger.Default.Warn(exception &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; item.Id.ToString());&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;再测试这一段程序，运行 70 秒就完成了数据转换，另外，查询对应关系那一句 SQL，因为针对的是刚恢复的数据库，所以用了大概 3、40 秒，实际使用查询管理器，在运行中的数据库执行那一句 SQL，只需要 1 秒左右就可以完成，所以，估计在实际转换的时候，3、40 秒就可以完成转换了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lephone/aggbug/1881840.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lephone/archive/2010/11/19/a_database_optimize_operation.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/07/05/using_cecil_to_modify_assembly.html</id><title type="text">使用 Cecil 修改 .Net 程序集</title><summary type="text">Cecil 是 Mono 的一个子项目，用于对程序集进行读写，并且已经用于 Mono 的调试，Reflector 也使用它作为底层库。最近把 DbEntry 使用 Emit 生成程序集的方式，改成了使用 Cecil 的方式，就我的感受来说，Cecil 是比较优秀的，有一些地方，比 Emit 使用起来还舒服的多；不过，有一些地方也比较繁琐。　　我使用的是 Git 里的最新版本，如果大家要测试的话，也...</summary><published>2010-07-05T13:45:00Z</published><updated>2010-07-05T13:45:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/07/05/using_cecil_to_modify_assembly.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/07/05/using_cecil_to_modify_assembly.html"/><content type="html">&lt;p&gt;Cecil 是 Mono 的一个子项目，用于对程序集进行读写，并且已经用于 Mono 的调试，Reflector 也使用它作为底层库。最近把 &lt;a href="http://dbentry.codeplex.com"&gt;DbEntry&lt;/a&gt; 使用 Emit 生成程序集的方式，改成了使用 Cecil 的方式，就我的感受来说，Cecil 是比较优秀的，有一些地方，比 Emit 使用起来还舒服的多；不过，有一些地方也比较繁琐。&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我使用的是 Git 里的最新版本，如果大家要测试的话，也建议使用 Git 版，所以，需要安装一个 Git 客户端。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这里，用一个非常简单的例子，说明一下 Cecil 的基本用法。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;首先，我们编写一个测试用的程序集 TestApp.exe :&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000;"&gt; TestApp&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Main()&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Main&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Before()&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Before&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; After()&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;After&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;　　然后，编写一个使用 Cecil 进行改写的应用 CecilTest.exe :&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Linq;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Mono.Cecil;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Mono.Cecil.Cil;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000;"&gt; CecilTest&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Main(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] args)&lt;br /&gt;        {&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(args.Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Usage: CecilTest TestApp.exe&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            var m &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; ModuleDefinition.ReadModule(args[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;]);&lt;br /&gt;&lt;br /&gt;            var prog &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; m.Types.First(p &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; p.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Program&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;            var main &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; prog.Methods.First(p &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; p.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Main&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;            var before &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; prog.Methods.First(p &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; p.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Before&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;            var after &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; prog.Methods.First(p &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; p.Name &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;After&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;br /&gt;            var il &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; main.Body.GetILProcessor();&lt;br /&gt;            il.InsertBefore(main.Body.Instructions[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;], il.Create(OpCodes.Call, before));&lt;br /&gt;            il.InsertBefore(main.Body.Instructions.Last(), il.Create(OpCodes.Call, after));&lt;br /&gt;&lt;br /&gt;            m.Write(args[&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;] &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;.exe&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;&lt;br /&gt;            Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Done&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;            Console.ReadLine();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;　　编译这两个项目，并且使用 CecilTest.exe 处理一下 TestApp.exe，生成 TestApp.exe.exe，运行 TestApp.exe，运行结果：&lt;br /&gt;Main&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;运行 TestApp.exe.exe，运行结果：&lt;/p&gt;&#xD;
&lt;p&gt;Before&lt;br /&gt;Main&lt;br /&gt;After&lt;br /&gt;&lt;br /&gt;　　可以看到，我们已经成功的在 Main 函数的前后，分别插入了一次函数调用。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;基本使用方法就是这样，大体和 Emit 类似，只是不止可以使用 Emit 函数，还可以直接修改程序集。当然，还有其它一些细节的不同，比如它的变量定义不是通过 ILProcessor，而是直接操作函数体的 Variables；再比如它没有 DeclareLabel 函数，跳转直接引用函数体的 Instruction 进行。另外，它可以只加载目标程序集，却不加载其依赖项，所以很多东西都分定义和引用两种。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;就目前来说，我认为它的效果是令人满意的。不过它最大的问题，在于泛型处理上。不是说不能做，而是太繁琐，有时候甚至是不可能。在 DbEntry 中，最后被泛型击败，采取了 Reflection+Cecil 的方式，这种方式简单易行，不过问题是，Reflection 需要加载程序集，除了可能出现无法加载依赖项的异常外，也无法简单的回写原文件。我在 Cecil 的 Git 上提交了 issue，不过作者回复，不觉得这是问题，所以我也懒得纠缠了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lephone/aggbug/1771697.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lephone/archive/2010/07/05/using_cecil_to_modify_assembly.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/05/24/csharp_gpgpu_with_opencl.html</id><title type="text">使用 OpenCL.Net 进行 C# GPU 并行编程</title><summary type="text">在 初探 C# GPU 通用计算技术 中，我使用 Accelerator 编写了一个简单的 GPU 计算程序。也简单看了一些 Brahma 的代码，从它的 SVN 最新代码看，Brahma 要转移到使用 OpenCL.Net 作为底层了，于是也去网上搜索了一下，发现了 OpenCL.Net 和另一个相关的项目 OpenCLTemplate。看了一些它的代码，颇像 DirectCompute 的风格...</summary><published>2010-05-24T12:47:00Z</published><updated>2010-05-24T12:47:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/05/24/csharp_gpgpu_with_opencl.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/05/24/csharp_gpgpu_with_opencl.html"/><content type="html">&lt;p&gt;在 &lt;a href="http://www.cnblogs.com/lephone/archive/2010/05/23/csharp_gpgpu.html"&gt;初探 C# GPU 通用计算技术&lt;/a&gt; 中，我使用 Accelerator 编写了一个简单的 GPU 计算程序。也简单看了一些 Brahma 的代码，从它的 SVN 最新代码看，Brahma 要转移到使用 OpenCL.Net 作为底层了，于是也去网上搜索了一下，发现了 &lt;a href="http://www.cmsoft.com.br/"&gt;OpenCL.Net 和另一个相关的项目 OpenCLTemplate&lt;/a&gt;。&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;看了一些它的代码，颇像 DirectCompute 的风格，其 GPU 程序是标准 C 代码，所以编写和阅读也容易一些，而 Host 程序是 C# 的，把 GPU 代码字符串传给编译器进行编译，然后就可以在 C# 对它进行调用，并且取回结果了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;安装了 ati-stream-sdk-v2.1-vista-win7-64，折腾了一下它的例子程序 FirstOpenCLProgram，运行时会抛出一个 InvalidContext 的异常，到它的论坛去问，版主建议我安装 ati 最新 driver 先，虽然觉得本本刚买没几天，应该驱动比较新，还是去安装了最新的驱动，果然不再报异常了。只是如果直接引用 OpenCLTemplate 下的 OpenCL.NET.dll 和 OpenCLTemplate.dll 的话，在初始化的时候会报空指针；而引用 FirstOpenCLProgram 下的这两个 dll 的话，则初始化时会闪现好几个控制台窗口，但是后续都是正常的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;既然正常了，就还是以上次那个程序，来看看 OpenCL 的方式，会不会有更大的速度提升。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;使用 OpenCL 的程序代码如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('8c91cea4-9bc8-4a45-9470-15895dce7fe4')"&gt;&#xD;
&lt;div id="cnblogs_code_open_8c91cea4-9bc8-4a45-9470-15895dce7fe4"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1024&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;readonly&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;float&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] _map;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; Code &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;@"&lt;/span&gt;&lt;span style="color: #800000;"&gt;&lt;br /&gt;__kernel void Test(__global float* v1)&lt;br /&gt;{&lt;br /&gt;    int i = get_global_id(0);&lt;br /&gt;    float p = v1[i];&lt;br /&gt;    v1[i] = p * p * p / 4 + 194;&lt;br /&gt;}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;readonly&lt;/span&gt;&lt;span style="color: #000000;"&gt; CLCalc.Program.Kernel _test;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;readonly&lt;/span&gt;&lt;span style="color: #000000;"&gt; CLCalc.Program.Variable _vmap;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;readonly&lt;/span&gt;&lt;span style="color: #000000;"&gt; CLCalc.Program.Variable[] _args;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;readonly&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] _workers;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; Form1()&lt;br /&gt;{&lt;br /&gt;    InitializeComponent();&lt;br /&gt;&lt;br /&gt;    _map &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;float&lt;/span&gt;&lt;span style="color: #000000;"&gt;[GridSize &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize];&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; y &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; y &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize; y&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize; x&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;        {&lt;br /&gt;            _map[x &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; y] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; y;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    CLCalc.InitCL();&lt;br /&gt;    CLCalc.Program.Compile(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] { Code });&lt;br /&gt;    _test &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; CLCalc.Program.Kernel(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Test&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;    _vmap &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; CLCalc.Program.Variable(_map);&lt;br /&gt;    _args &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] { _vmap };&lt;br /&gt;    _workers &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] { GridSize &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize };&lt;br /&gt;&lt;br /&gt;    Render();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Start_Click(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;    var stopwatch &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Stopwatch();&lt;br /&gt;    stopwatch.Start();&lt;br /&gt;&lt;br /&gt;    _test.Execute(_args, _workers);&lt;br /&gt;    _vmap.ReadFromDeviceTo(_map);&lt;br /&gt;&lt;br /&gt;    var time &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; stopwatch.ElapsedMilliseconds;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Text &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; time.ToString();&lt;br /&gt;    Render();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Render()&lt;br /&gt;{&lt;br /&gt;    var workingBitmap &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Bitmap(pictureBox1.Width, pictureBox1.Height);&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; y &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; y &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; pictureBox1.Height; y&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; pictureBox1.Width; x&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;        {&lt;br /&gt;            workingBitmap.SetPixel(x, y, Color.FromArgb(&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;0x1000000&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;)_map[x &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; y &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;]));&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    pictureBox1.Image &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; workingBitmap;&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;运行程序，点击 4 次按钮，显示图形和前两个程序相同，说明程序运算正常，4 次时间为：8、8、7、8。比使用 Accelerator 的程序速度也快了 5 倍以上。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;因为是标准 C 程序，所以我们的自由度很大，我也在 OpenCL 下实现了一下 Life 游戏，C# 部分的代码就不贴了，GPU 代码如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('40d31a13-a286-4da4-a4d7-4b02030f3bb1')"&gt;&#xD;
&lt;div id="cnblogs_code_open_40d31a13-a286-4da4-a4d7-4b02030f3bb1"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;#define&lt;/span&gt;&lt;span style="color: #000000;"&gt; width 512&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;#define&lt;/span&gt;&lt;span style="color: #000000;"&gt; length 262144&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetValue(__global &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; v, &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; index)&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(index &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;||&lt;/span&gt;&lt;span style="color: #000000;"&gt; index &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; length)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;    }&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; v[index] &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;?&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; : &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;__kernel &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Test(__global &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; v)&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; i &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; get_global_id(&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; topLeft &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetValue(v, i &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; width &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; top &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetValue(v, i &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; width);&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; topRight &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetValue(v, i &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; width &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; left &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetValue(v, i &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; current &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetValue(v, i);&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; right &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetValue(v, i &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; bottomLeft &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetValue(v, i &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; width &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; bottom &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetValue(v, i &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; width);&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; bottomRight &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetValue(v, i &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; width &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; liveNeighbors &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; topLeft &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; top &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; topRight &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; left &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; right &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; bottomLeft &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; bottom &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; bottomRight;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt;(current &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;    {&lt;br /&gt;        v[i] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; ((liveNeighbors &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;/span&gt;&lt;span style="color: #000000;"&gt;||&lt;/span&gt;&lt;span style="color: #000000;"&gt; (liveNeighbors &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;)) &lt;/span&gt;&lt;span style="color: #000000;"&gt;?&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; : &lt;/span&gt;&lt;span style="color: #800080;"&gt;255&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;    }&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;&lt;br /&gt;    {&lt;br /&gt;        v[i] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; (liveNeighbors &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;) &lt;/span&gt;&lt;span style="color: #000000;"&gt;?&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;255&lt;/span&gt;&lt;span style="color: #000000;"&gt; : &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;    }&lt;br /&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;很长时间不用 C，有很多像函数声明顺序等规则都忘了，好的一点是 OpenCL.Net 中还提供了 OpenCLCodeChecker，用来进行代码检测，同时也在侧边栏里提供了语言帮助，只是它的检测稍嫌弱智，代码稍微复杂，提示的错误位置很奇怪，有时候告知编译出错，Log 里面却没有任何错误信息。不过总体来说，帮助还是很大就是了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这个 Life 程序，有一个小 Bug，在于没有判断超出右边界的代码，所以如果左边有生物，右边虽然原来没有生物，也会无中生有 :)&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;总的来说，用 OpenCL.Net 编程，感觉还是很愉快的。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lephone/aggbug/1743029.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lephone/archive/2010/05/24/csharp_gpgpu_with_opencl.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/05/23/csharp_gpgpu.html</id><title type="text">初探 C# GPU 通用计算技术</title><summary type="text">GPU 的并行计算能力高于 CPU，所以最近也有很多利用 GPU 的项目出现在我们的视野中，在 InfoQ 上看到这篇介绍 Accelerator-V2 的文章，它是微软研究院的研究项目，需要注册后才能下载，感觉作为我接触 GPU 通用运算的第一步还不错，于是去下载了回来。在安装包里，包含了几个例子程序，比如著名的 Life 游戏，不过，Life 游戏，相对于刚接触 GPU 运算的我，还是稍显复杂...</summary><published>2010-05-23T11:02:00Z</published><updated>2010-05-23T11:02:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/05/23/csharp_gpgpu.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/05/23/csharp_gpgpu.html"/><content type="html">&lt;p&gt;GPU 的并行计算能力高于 CPU，所以最近也有很多利用 GPU 的项目出现在我们的视野中，在 InfoQ 上看到这篇介绍 &lt;a href="http://www.infoq.com/cn/news/2010/01/Accelerator-V2"&gt;Accelerator-V2&lt;/a&gt; 的文章，它是微软研究院的研究项目，需要注册后才能下载，感觉作为我接触 GPU 通用运算的第一步还不错，于是去下载了回来。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在安装包里，包含了几个例子程序，比如著名的 Life 游戏，不过，Life 游戏，相对于刚接触 GPU 运算的我，还是稍显复杂了。于是简化一下，只是进行一些简单的计算，发现，DX9Target.ToArray 如果返回参数是 int 数组的话，则会爆出&amp;ldquo;未支持的操作&amp;rdquo;的异常，想想也对，显卡确实是精于浮点运算的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;本来，我以为，GPU 运算是 DirectX 11 才有的功能，但是 Accelerator 支持的却是 DirectX 9，想来 DirectX 11 支持的运算能力更高、方式更简单吧。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;为了简单比较一下 CPU 和 GPU 的速度，也写了一个 .net 4 的并行运算的程序，因为 DX9Target 不支持 int，所以这里的数组也用 float，如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('2585eca1-5566-4eb0-9e11-c24f3050b359')"&gt;&#xD;
&lt;div id="cnblogs_code_open_2585eca1-5566-4eb0-9e11-c24f3050b359"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1024&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;float&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] _map;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; Form1()&lt;br /&gt;{&lt;br /&gt;    InitializeComponent();&lt;br /&gt;    _map &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;float&lt;/span&gt;&lt;span style="color: #000000;"&gt;[GridSize &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize];&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; y &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; y &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize; y&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize; x&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;        {&lt;br /&gt;            _map[x &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; y] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; y;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    Render();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Start_Click(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;    var stopwatch &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Stopwatch();&lt;br /&gt;    stopwatch.Start();&lt;br /&gt;    _map &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; _map.AsParallel().Select(p &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; p &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; p &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; p &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;194&lt;/span&gt;&lt;span style="color: #000000;"&gt;).ToArray();&lt;br /&gt;    var time &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; stopwatch.ElapsedMilliseconds;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Text &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; time.ToString();&lt;br /&gt;    Render();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Render()&lt;br /&gt;{&lt;br /&gt;    var workingBitmap &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Bitmap(pictureBox1.Width, pictureBox1.Height);&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; y &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; y &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; pictureBox1.Height; y&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; pictureBox1.Width; x&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;        {&lt;br /&gt;            workingBitmap.SetPixel(x, y, Color.FromArgb(&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;0x1000000&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;)_map[x &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; y &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;]));&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    pictureBox1.Image &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; workingBitmap;&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;而使用 Accelerator 的代码如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('df77c8e0-4801-4bad-875d-11c985b15ecb')"&gt;&#xD;
&lt;div id="cnblogs_code_open_df77c8e0-4801-4bad-875d-11c985b15ecb"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;1024&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;readonly&lt;/span&gt;&lt;span style="color: #000000;"&gt; DX9Target _target;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;float&lt;/span&gt;&lt;span style="color: #000000;"&gt;[,] _map;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; Form1()&lt;br /&gt;{&lt;br /&gt;    InitializeComponent();&lt;br /&gt;    _target &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DX9Target();&lt;br /&gt;    _map &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;float&lt;/span&gt;&lt;span style="color: #000000;"&gt;[GridSize, GridSize];&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; y &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; y &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize; y&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; GridSize; x&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;        {&lt;br /&gt;            _map[x, y] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; y;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    Render();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Start_Click(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;    var stopwatch &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Stopwatch();&lt;br /&gt;    stopwatch.Start();&lt;br /&gt;&lt;br /&gt;    var p &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FloatParallelArray(_map);&lt;br /&gt;    p &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; p &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; p &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; p &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;+&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;194&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;    _target.ToArray(p, &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;out&lt;/span&gt;&lt;span style="color: #000000;"&gt; _map);&lt;br /&gt;&lt;br /&gt;    var time &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; stopwatch.ElapsedMilliseconds;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Text &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; time.ToString();&lt;br /&gt;    Render();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Render()&lt;br /&gt;{&lt;br /&gt;    var workingBitmap &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Bitmap(pictureBox1.Width, pictureBox1.Height);&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; y &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; y &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; pictureBox1.Height; y&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;for&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; x &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; pictureBox1.Width; x&lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br /&gt;        {&lt;br /&gt;            workingBitmap.SetPixel(x, y, Color.FromArgb(&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #800080;"&gt;0x1000000&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;|&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;)_map[x &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;， y &lt;/span&gt;&lt;span style="color: #000000;"&gt;*&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;]));&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    pictureBox1.Image &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; workingBitmap;&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;用我的笔记本（CPU 为 Core i5 430, 显卡为 ATI 5650）测试，对它们两个程序，都点击几次 Start 按钮，发现运行 3 次左右，图片框会变成全黑，这时，普通并行程序运算速度变慢，而 GPU 程序运行速度无明显变化，普通并行程序 4 次值为：96，89，277，291，而 GPU 程序 4 次值为：71，40，35，50。单就这个测试来说，在我的电脑上，使用 GPU 的程序，大概比普通并行程序快一倍左右吧。这个测试本身，其实不见得很公平，结果仅供参考。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;不过，在 Accelerator 中的并行编程，明显感觉受到的约束很大，平常很容易的代码，要改成这种并行模式，需要花费很多力气，有些逻辑甚至无法实现。相对于 Accelerator，&lt;a href="http://www.infoq.com/cn/news/2010/05/Brahma"&gt;Brahma&lt;/a&gt; 的代码写起来就容易得多，也更易于阅读，其 Life 游戏的例子程序读起来简单而清晰，可惜我编译了 Brahma v0.1 和 v0.4，在我的电脑上，DirectX 的例子程序没有效果，而 OpenGL 的例子程序则会报一个&amp;ldquo;The generated GLSL was invalid&amp;rdquo;的异常，看来还需要等它完善之后才能使用吧。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lephone/aggbug/1742189.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lephone/archive/2010/05/23/csharp_gpgpu.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/05/15/think_of_design_pattern.html</id><title type="text">我的设计模式观</title><summary type="text">设计模式是有效的架构设计方法，甚至可以说是面向对象编程的范例，不过，学习设计模式比学习一种同类型的语言（比如Java之于C#）困难得多。简历中不少人会或多或少提到设计模式，但是真的问时，大多又是只能说出&amp;ldquo;工厂&amp;rdquo;，&amp;ldquo;单例&amp;rdquo;之类的模式，这些模式是比较简单，同时也是重要的模式，不过，创建型模式更像味精，用于调味其它的结构性模式，脱离了结构性模式，创建型模式...</summary><published>2010-05-15T01:10:00Z</published><updated>2010-05-15T01:10:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/05/15/think_of_design_pattern.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/05/15/think_of_design_pattern.html"/><content type="html">&lt;p&gt;设计模式是有效的架构设计方法，甚至可以说是面向对象编程的范例，不过，学习设计模式比学习一种同类型的语言（比如Java之于C#）困难得多。&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;简历中不少人会或多或少提到设计模式，但是真的问时，大多又是只能说出&amp;ldquo;工厂&amp;rdquo;，&amp;ldquo;单例&amp;rdquo;之类的模式，这些模式是比较简单，同时也是重要的模式，不过，创建型模式更像味精，用于调味其它的结构性模式，脱离了结构性模式，创建型模式也就失去了存在的意义。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;所以，从这个角度来说，GoF虽然能力很强，写书的水平实在不怎么样，把创建型模式放在前面，失去了循序渐进的好处，使得很多人停留在了&amp;ldquo;工厂&amp;rdquo;，&amp;ldquo;单例&amp;rdquo;，却不真的知道为什么要用它们。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;但是，不少结构性模式的差别很微妙，也比较难精通，在我看来，对于初学者，很多停留在&amp;ldquo;工厂&amp;rdquo;&amp;ldquo;单例&amp;rdquo;固然不好，即使能一股脑把23种经典设计模式都看完，也不是一个正确的做法，只会在这些微妙差别中迷失。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;所以，我推荐给初学者的做法是：忘掉所有你阅读过的设计模式，承认自己完全不理解设计模式，并且主攻一种我认为最基础，或者说最重要的结构性设计模式：策略模式。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;或者更进一步，也不要想什么策略模式，而是去熟悉面向对象的基础知识，了解什么叫接口，并且在你的项目中，极力思考什么情况下，使用接口可以灵巧的实现需求，而且针对未来可能的同类型改变，可以轻松的应对？极力思考使用接口怎样可以分离类和类之间的关系，使之都依赖于接口，而不是互相纠缠在一起。使用类图可能能更好的帮助你进行设计，从类图上，查看你的类之间的关系，使用你能想到的方法，消除扑朔迷离的类依赖，使之尽量清晰、简洁。一旦你完成了面向接口编程的转变，你会发现，你自然而然的需要一种方式，来创建你的接口的派生类，也就是工厂模式，有时候，简单工厂不能满足要求，可能还需要进行一些扩展&amp;hellip;&amp;hellip;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;现在，再回来从头阅读一遍GoF的那本薄薄的小书《设计模式》，你可能会发现有些创建型模式正是你项目里需要的，很多结构性模式和你使用接口的方法是如此相像，也许你会发现你不止重新&amp;ldquo;发明&amp;rdquo;了一种模式，而这一次，因为你完全理解为什么你需要使用接口，为什么需要使用工厂，也才能准确的理解相似的模式之间的些微差异，并且对不同模式的使用时机进行更好的评估。你也会发现，有一些模式，比如中介者，对于 .Net 开发人员来说，几乎人人天天都在用；有一些模式，比如原型，使用反射加特性可以更好的实现等等。现在我想你会和我一样的觉得，原来面向对象编程的真谛在于设计模式&amp;hellip;&amp;hellip;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;最后说两句题外话：一，无论什么时候，通读一遍MSDN都是一个快速提高的好方法；二，软件设计很多时候是在选择，并不是使用新技术就一定是好的，并不是多用设计模式就一定是好的，将正确的技术，用在正确的地方，才是一个软件设计师的能力所在。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lephone/aggbug/1735933.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lephone/archive/2010/05/15/think_of_design_pattern.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/04/24/serialization_speed_test.html</id><title type="text">有关于序列化速度的测试</title><summary type="text">项目里数据库表有很多字段，而且有不少字段不确定长度，所以决定，把大多数不常用字段用 XML 序列化的方式，保存到一个字段内，不过却发现，从网上取一条 10K 左右的 XML 数据，反序列化，解析、转义，然后分别设置到4、5个对象中，这些对象，再对自身的不常用字段进行 XML 序列化，然后保存对象到数据库，竟然要花 5 秒左右的时间。　　下载了一个 DotTrace + TestDriven.Net...</summary><published>2010-04-24T05:27:00Z</published><updated>2010-04-24T05:27:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/04/24/serialization_speed_test.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/04/24/serialization_speed_test.html"/><content type="html">&lt;p&gt;项目里数据库表有很多字段，而且有不少字段不确定长度，所以决定，把大多数不常用字段用 XML 序列化的方式，保存到一个字段内，不过却发现，从网上取一条 10K 左右的 XML 数据，反序列化，解析、转义，然后分别设置到4、5个对象中，这些对象，再对自身的不常用字段进行 XML 序列化，然后保存对象到数据库，竟然要花 5 秒左右的时间。&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;下载了一个 DotTrace + TestDriven.Net，用它对单元测试进行了分析，发现，这 5 秒左右的时间，有 4 秒多都花在了 XML 序列化上，那么解决问题的方法就比较明确，改用另外的序列化方法。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;因为项目使用了 Coolite，Json 就成了一个比较简单的选择，于是用 Coolite 自带的 Json 序列化（其实是 Newtonsoft Json）进行序列化测试，对于我测试的 7K 左右的大多数是字符串的数据来说，Json 的速度大概是 XML 的 3 倍左右，而且序列化出的字符串，也比 XML 小三分之一左右。于是把数据库中的序列化字段改成 Json，速度马上有了一个大的提高。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;不过，在网上搜到了&lt;a href="http://www.javaeye.com/wiki/phprpc/1493-java-phprpc-hessian-burlap-xml-serialization-efficiency-comparison"&gt;一篇文章&lt;/a&gt;，比较了几种序列化方式，说是 PHP-RPC 是综合效果最好的，于是也找来，一并写了测试程序如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('ba241645-87a5-4b1e-a67b-c9e6eb8ae7ac')"&gt;&#xD;
&lt;div id="cnblogs_code_open_ba241645-87a5-4b1e-a67b-c9e6eb8ae7ac"&gt;&#xD;
&lt;pre&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;readonly&lt;/span&gt;&lt;span style="color: #000000;"&gt; Stopwatch Stopwatch &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Stopwatch();&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; _temp &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;""&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Main()&lt;br /&gt;    {&lt;br /&gt;        var xmlStr &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; ResourceHelper.ReadToEnd(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt; (Program), &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.xml&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br /&gt;        var trade &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; SingleTrade.FromXml(xmlStr);&lt;br /&gt;&lt;br /&gt;        CheckTwoWayTime(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;XML&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, () &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; _temp &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; trade.ToXml(), () &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; SingleTrade.FromXml(_temp));&lt;br /&gt;        CheckTwoWayTime(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;JSON&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, () &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; _temp &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; JSON.Serialize(trade), () &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; JSON.Deserialize&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;SingleTrade&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(_temp));&lt;br /&gt;        CheckTwoWayTime(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;PHP&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, () &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; _temp &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; PhpSerialize(trade), () &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; PhpDeserialize(_temp));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; CheckTwoWayTime(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; text, CallbackVoidHandler sCallback, CallbackVoidHandler dCallback)&lt;br /&gt;    {&lt;br /&gt;        var s &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; CheckTime(sCallback);&lt;br /&gt;        var d &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; CheckTime(dCallback);&lt;br /&gt;        Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;{0} Serialize MS: {1}, Deserialize MS: {2}, Length of string: {3}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, text, s, d, _temp.Length);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;long&lt;/span&gt;&lt;span style="color: #000000;"&gt; CheckTime(CallbackVoidHandler callback)&lt;br /&gt;    {&lt;br /&gt;        Stopwatch.Reset();&lt;br /&gt;        Stopwatch.Start();&lt;br /&gt;        callback();&lt;br /&gt;        var ms &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Stopwatch.ElapsedMilliseconds;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; ms;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; PhpSerialize(SingleTrade obj)&lt;br /&gt;    {&lt;br /&gt;        var php &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; org.phprpc.util.PHPFormatter();&lt;br /&gt;        var m &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.IO.MemoryStream();&lt;br /&gt;        php.Serialize(m, obj);&lt;br /&gt;        var result &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Convert.ToBase64String(m.ToArray());&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; result;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; SingleTrade PhpDeserialize(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; s)&lt;br /&gt;    {&lt;br /&gt;        var php &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; org.phprpc.util.PHPFormatter();&lt;br /&gt;        var m &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.IO.MemoryStream(Convert.FromBase64String(s)) {Position &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;};&lt;br /&gt;        var result &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; (SingleTrade)php.Deserialize(m);&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; result;&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;　　运行了三次这个程序，三次的结果如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;C:\Debug&amp;gt;Besten.Migration.exe&lt;br /&gt;XML Serialize MS: 148, Deserialize MS: 161, Length of string: 7233&lt;br /&gt;JSON Serialize MS: 82, Deserialize MS: 29, Length of string: 5344&lt;br /&gt;PHP Serialize MS: 8, Deserialize MS: 18, Length of string: 8836&lt;/p&gt;&#xD;
&lt;p&gt;C:\Debug&amp;gt;Besten.Migration.exe&lt;br /&gt;XML Serialize MS: 161, Deserialize MS: 165, Length of string: 7233&lt;br /&gt;JSON Serialize MS: 74, Deserialize MS: 42, Length of string: 5344&lt;br /&gt;PHP Serialize MS: 13, Deserialize MS: 17, Length of string: 8836&lt;/p&gt;&#xD;
&lt;p&gt;C:\Debug&amp;gt;Besten.Migration.exe&lt;br /&gt;XML Serialize MS: 165, Deserialize MS: 180, Length of string: 7233&lt;br /&gt;JSON Serialize MS: 67, Deserialize MS: 24, Length of string: 5344&lt;br /&gt;PHP Serialize MS: 9, Deserialize MS: 26, Length of string: 8836&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;可以看到，PHP-RPC 序列化的速度，大概是 XML 的 10 到 20 倍之间，反序列化的速度也是 XML 的 8 倍左右，所以，项目下一步的计划就是把序列化字段的方法改成 PHP-RPC 了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;看了一下 PHP-RPC 的序列化方法描述，它的字符串序列化比较特殊，使用前置长度而不进行转义的方式，所以速度比较快、而占用内存比较小也就不奇怪了。只是还没研究它序列化出的字节数组究竟是否直接就是字符串，而不需要用 Base64 呢？&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lephone/aggbug/1719270.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lephone/archive/2010/04/24/serialization_speed_test.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lephone/archive/2010/04/17/dbentry3_9.html</id><title type="text">DbEntry.Net 3.9</title><summary type="text">这是我设计的一个轻量级的 .Net ORM (Object Relational Mapping) 数据访问及 WEB 框架。对于 ORM 和 Sql 调用，它都拥有清晰和易用的接口，目前支持 SqlServer、SQLite、MySql、Access、Firebird、PostgreSQL、Oracle 等数据库。对于 WEB 开发，它既支持 ASP.NET 2.0 的 DataSource 方...</summary><published>2010-04-17T08:42:00Z</published><updated>2010-04-17T08:42:00Z</updated><author><name>梁利锋</name><uri>http://www.cnblogs.com/lephone/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lephone/archive/2010/04/17/dbentry3_9.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lephone/archive/2010/04/17/dbentry3_9.html"/><content type="html">&lt;p&gt;这是我设计的一个轻量级的 .Net ORM (Object Relational Mapping) 数据访问及 WEB 框架。对于 ORM 和 Sql 调用，它都拥有清晰和易用的接口，目前支持 SqlServer、SQLite、MySql、Access、Firebird、PostgreSQL、Oracle 等数据库。对于 WEB 开发，它既支持 ASP.NET 2.0 的 DataSource 方式，也支持 Ruby On Rails 风格的 MVC 方式。支持 Linq 方式的查询，也提供一个简单的 IoC。&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;目前，数据库部分已经支持多主键、多表联合查询、快速分页集合、隐式数据库事务、连贯API查询、ActiveRecord风格查询、动态对象、部分保存、自动创建数据表、一对一、一对多、多对多关系等功能，具体实现请参阅 Samples 中的例子程序和单元测试的内容。&lt;/p&gt;&#xD;
&lt;p&gt;而 DataSource 部分，因为绑定数据访问组件，所以可以只需要修改配置文件，不需要修改任何代码的在不同的数据之间切换。另外，还支持按命名约定的方式绑定&amp;ldquo;新建&amp;rdquo;和&amp;ldquo;编辑&amp;rdquo;页面的控件，以最少的代码完成输入、验证、保存等一系列操作。&lt;/p&gt;&#xD;
&lt;p&gt;Rails 风格的 MVC 框架目前已经完成 MVC 部分，脚手架，基类中的 LinkTo、UrlTo 等快捷函数，Http Get 支持等。目前脚手架部分没有数据验证模块，不过，自己写的 MVC 代码可以自行实现验证。&lt;/p&gt;&#xD;
&lt;p&gt;这个版本中，例子程序访问的数据库主要是 Access，而单元测试使用的数据库是 SQLite，通过修改配置文件中数据源部分，可以使之不需要重新编译即可工作于其它数据库上。配置部分通过 App.config 进行，请参阅 Samples 中的例子程序中的 App.config 和 UnitTest 项目内嵌的配置文件 UnitTest.config.xml 。所有例子程序在 MS Sql Server 2005 Express、MS Sql Server 2008 Express、 MS Access 2003、MySql 5.0、SQLite 3、Firebird 2.1.0, PostgreSQL 8.3.3 和 Oracle 10g Express 上测试过。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/img/lephone/201004/2010041716391644.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;v3.9 版主要的改变为：&lt;br /&gt;　　&amp;middot;修正 Bug&lt;br /&gt;　　&amp;middot;对特定数据库支持增强&lt;br /&gt;　　&amp;middot;合并 Lephone.Linq 到其他程序集&lt;br /&gt;　　&amp;middot;对 Linq 支持增强&lt;br /&gt;　　&amp;middot;对 MVC 支持增强&lt;/p&gt;&#xD;
&lt;p&gt;下载本组件和浏览文档请访问 &lt;a target="_blank" href="http://www.codeplex.com/DbEntry/"&gt;http://www.codeplex.com/DbEntry/&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lephone/aggbug/1714301.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lephone/archive/2010/04/17/dbentry3_9.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
