<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>H31家园</title>
<link>http://h31home.com/</link>
<Description>欢迎光临使用H31家园</Description>
<language>zh-cn</language>
<copyright>Copyright 2006-2008 H31Home</copyright>
<webMaster>miao.whu@Gmail.com</webMaster>
<image>
	<title>H31家园</title> 
	<url>http://h31home.com/images/miao.gif</url> 
	<link>http://h31home.com/</link> 
	<description>欢迎光临使用H31家园</description> 
</image>
<item><link>http://h31home.com/h312005/blogview.asp?ID=998</link><title><![CDATA[分布式基础学习]]></title><author>admin</author><category>Linux学习</category><pubDate>2009-2-23 15:14:31</pubDate><guid>http://h31home.com/h312005/blogview.asp?ID=998</guid><description><![CDATA[http://www.cnblogs.com/duguguiyu/archive/2009/02/22/1396034.html

所谓分布式，在这里，很狭义的指代以Google的三驾马车，GFS、Map/Reduce、BigTable为框架核心的分布式存储和计算系统。通常如我一样初学的人，会以Google这几份经典的论文作为开端的。它们勾勒出了分布式存储和计算的一个基本蓝图，已可窥见其几分风韵，但终究还是由于缺少一些实现的代码和示例，色彩有些斑驳，缺少了点感性。幸好我们还有Open Source，还有Hadoop。Hadoop是一个基于Java实现的，开源的，分布式存储和计算的项目。作为这个领域最富盛名的开源项目之一，它的使用者也是大牌如云，包括了Yahoo，Amazon，Facebook等等（好吧，还可能有校内，不过这真的没啥分量...）。Hadoop本身，实现的是分布式的文件系统HDFS，和分布式的计算（Map/Reduce）框架，此外，它还不是一个人在战斗，Hadoop包含一系列扩展项目，包括了分布式文件数据库HBase（对应Google的BigTable），分布式协同服务ZooKeeper（对应Google的Chubby），等等。。。
如此，一个看上去不错的黄金搭档浮出水面，Google的论文 + Hadoop的实现，顺着论文的框架看具体的实现，用实现来进一步理解论文的逻辑，看上去至少很美。网上有很多前辈们，做过Hadoop相关的源码剖析工作，我关注最多的是这里，目前博主已经完成了HDFS的剖析工作，Map/Reduce的剖析正火热进行中，更新频率之高，剖析之详尽，都是难得一见的，所以，走过路过一定不要错过了。此外，还有很多Hadoop的关注者和使用者贴过相关的文章，比如：这里，这里。也可以去Hadoop的中文站点（不知是民间还是官方...），搜罗一些学习资料。。。
我个人从上述资料中受益匪浅，而我自己要做的整理，与原始的源码剖析有些不同，不是依照实现的模块，而是基于论文的脉络和实现这样系统的基本脉络来进行的，也算，从另一个角度给出一些东西吧。鉴于个人对于分布式系统的理解非常的浅薄，缺少足够的实践经验，深入的问题就不班门弄斧了，仅做梳理和解析，大牛至此，可绕路而行了。。。
一. 分布式文件系统

分布式文件系统，在整个分布式系统体系中处于最低层最基础的地位，存储嘛，没了数据，再好的计算平台，再完善的数据库系统，都成了无水之舟了。那么，什么是分布式文件系统，顾名思义，就是分布式+文件系统。它包含这两个方面的内涵，从文件系统的客户使用的角度来看，它就是一个标准的文件系统，提供了一系列API，由此进行文件或目录的创建、移动、删除，以及对文件的读写等操作。从内部实现来看，分布式的系统则不再和普通文件系统一样负责管理本地磁盘，它的文件内容和目录结构都不是存储在本地磁盘上，而是通过网络传输到远端系统上。并且，同一个文件存储不只是在一台机器上，而是在一簇机器上分布式存储，协同提供服务，正所谓分布式。。。
因此，考量一个分布式文件系统的实现，其实不妨可以从这两方面来分别剖析，而后合二为一。首先，看它如何去实现文件系统所需的基本增删改查的功能。然后，看它如何考虑分布式系统的特点，提供更好的容错性，负载平衡，等等之类的。这二者合二为一，就明白了一个分布式文件系统，整体的实现模式。。。
I. 术语对照
说任何东西，都需要统一一下语言先，不然明明说的一个意思，却容易被理解到另一个地方去。Hadoop的分布式文件系统HDFS，基本是按照Google论文中的GFS的架构来实现的。但是，HDFS为了彰显其不走寻常路的本性，其中的大量术语，都与GFS截然不同。明明都是一个枝上长的土豆，它偏偏就要叫山药蛋，弄得水火不容的，苦了我们看客。秉承老好人，谁也不得罪的方针，文中，既不采用GFS的叫法，也不采用Hadoop的称谓，而是另辟蹊径，自立门户，搞一套自己的中文翻译，为了避免不必要的痛楚，特此先来一帖术语对照表，要不懂查一查，包治百病。。。

文中所用翻译 HDFS中的术语 GFS中的术语 术语解释 
主控服务器 NameNode Master 整个文件系统的大脑，它提供整个文件系统的目录信息，并且管理各个数据服务器。 
数据服务器 DataNode Chunk Server 分布式文件系统中的每一个文件，都被切分成若干个数据块，每一个数据块都被存储在不同的服务器上，此服务器称之为数据服务器。 
数据块 Block Chunk 每个文件都会被切分成若干个块，每一块都有连续的一段文件内容，是存储的基恩单位，在这里统一称做数据块。 
数据包 Packet 无 客户端写文件的时候，不是一个字节一个字节写入文件系统的，而是累计到一定数量后，往文件系统中写入一次，每发送一次的数据，都称为一个数据包。 
传输块 Chunk 无 在每一个数据包中，都会将数据切成更小的块，每一个块配上一个奇偶校验码，这样的块，就是传输块。 
备份主控服务器 SecondaryNameNode 无 备用的主控服务器，在身后默默的拉取着主控服务器 的日志，等待主控服务器牺牲后被扶正。 


*注：本文采用的Hadoop是0.19.0版本。
II. 基本架构
1. 服务器介绍
与单机的文件系统不同，分布式文件系统不是将这些数据放在一块磁盘上，由上层操作系统来管理。而是存放在一个服务器集群上，由集群中的服务器，各尽其责，通力合作，提供整个文件系统的服务。其中重要的服务器包括：主控服务器（Master/NameNode），数据服务器（ChunkServer/DataNode），和客户服务器。HDFS和GFS都是按照这个架构模式搭建的。个人觉得，其中设计的最核心内容是：文件的目录结构独立存储在一个主控服务器上，而具体文件数据，拆分成若干块，冗余的存放在不同的数据服务器上。
存储目录结构的主控服务器，在GFS中称为Master，在HDFS中称为NameNode。这两个名字，叫得都有各自的理由，是瞎子摸象各表一面。Master是之于数据服务器来叫的，它做为数据服务器的领导同志存在，管理各个数据服务器，收集它们的信息，了解所有数据服务器的生存现状，然后给它们分配任务，指挥它们齐心协力为系统服务；而NameNode是针对客户端来叫的，对于客户端而言，主控服务器上放着所有的文件目录信息，要找一个文件，必须问问它，由此而的此名。。。
主控服务器在整个集群中，同时提供服务的只存在一个，如果它不幸牺牲的话，会有后备军立刻前赴后继的跟上，但，同一时刻，需要保持一山不容二虎的态势。这种设计策略，避免了多台服务器间即时同步数据的代价，而同时，它也使得主控服务器很可能成为整个架构的瓶颈所在。因此，尽量为主控服务器减负，不然它做太多的事情，就自然而然的晋升成了一个分布式文件系统的设计要求。。。
每一个文件的具体数据，被切分成若干个数据块，冗余的存放在数据服务器。通常的配置，每一个数据块的大小为64M，在三个数据服务器上冗余存放（这个64M，不是随便得来的，而是经过反复实践得到的。因为如果太大，容易造成热点的堆叠，大量的操作集中在一台数据服务器上，而如果太小的话，附加的控制信息传输成本，又太高了。因此没有比较特定的业务需求，可以考虑维持此配置...）。数据服务器是典型的四肢发达头脑简单的苦力，其主要的工作模式就是定期向主控服务器汇报其状况，然后等待并处理命令，更快更安全的存放好数据。。。
此外，整个分布式文件系统还有一个重要角色是客户端。它不和主控服务和数据服务一样，在一个独立的进程中提供服务，它只是以一个类库（包）的模式存在，为用户提供了文件读写、目录操作等APIs。当用户需要使用分布式文件系统进行文件读写的时候，把客户端相关包给配置上，就可以通过它来享受分布式文件系统提供的服务了。。。
2. 数据分布
一个文件系统中，最重要的数据，其实就是整个文件系统的目录结构和具体每个文件的数据。具体的文件数据被切分成数据块，存放在数据服务器上。每一个文件数据块，在数据服务器上都表征为出双入队的一对文件（这是普通的Linux文件），一个是数据文件，一个是附加信息的元文件，在这里，不妨把这对文件简称为数据块文件。数据块文件存放在数据目录下，它有一个名为current的根目录，然后里面有若干个数据块文件和从dir0-dir63的最多64个的子目录，子目录内部结构等同于current目录，依次类推（更详细的描述，参见这里）。个人觉得，这样的架构，有利于控制同一目录下文件的数量，加快检索速度。。。
这是磁盘上的物理结构，与之对应的，是内存中的数据结构，用以表征这样的磁盘结构，方便读写操作的进行。Block类用于表示数据块，而FSDataset类是数据服务器管理文件块的数据结构，其中，FSDataset.FSDir对应着数据块文件和目录，FSDataset.FSVolume对应着一个数据目录，FSDataset.FSVolumeSet是FSVolume的集合，每一个FSDataset有一个FSVolumeSet。多个数据目录，可以放在不同的磁盘上，这样有利于加快磁盘操作的速度。相关的类图，可以参看这里 。。。
此外，与FSVolume对应的，还有一个数据结构，就是DataStorage，它是Storage的子类，提供了升级、回滚等支持。但与FSVolume不一样，它不需要了解数据块文件的具体内容，它只知道有这么一堆文件放这里，会有不同版本的升级需求，它会处理怎么把它们升级回滚之类的业务（关于Storage，可以参见这里）。而FSVolume提供的接口，都基本上是和Block相关的。。。
相比数据服务器，主控服务器的数据量不大，但逻辑更为复杂。主控服务器主要有三类数据：文件系统的目录结构数据，各个文件的分块信息，数据块的位置信息（就数据块放置在哪些数据服务器上...）。在GFS和HDFS的架构中，只有文件的目录结构和分块信息才会被持久化到本地磁盘上，而数据块的位置信息则是通过动态汇总过来的，仅仅存活在内存数据结构中，机器挂了，就灰飞烟灭了。每一个数据服务器启动后，都会向主控服务器发送注册消息，将其上数据块的状况都告知于主控服务器。俗话说，简单就是美，根据DRY原则，保存的冗余信息越少，出现不一致的可能性越低，付出一点点时间的代价，换取了一大把逻辑上的简单性，绝对应该是一个包赚不赔的买卖。。。
在HDFS中，FSNamespacesystem类就负责保管文件系统的目录结构以及每个文件的分块状况的，其中，前者是由FSDirectory类来负责，后者是各个INodeFile本身维护。在INodeFile里面，有一个BlockInfo的数组，保存着与该文件相关的所有数据块信息，BlockInfo中包含了从数据块到数据服务器的映射，INodeFile只需要知道一个偏移量，就可以提供相关的数据块，和数据块存放的数据服务器信息。。。
3、服务器间协议
在Hadoop的实现中，部署了一套RPC机制，以此来实现各服务间的通信协议。在Hadoop中，每一对服务器间的通信协议，都定义成为一个接口。服务端的类实现该接口，并且建立RPC服务，监听相关的接口，在独立的线程处理RPC请求。客户端则可以实例化一个该接口的代理对象，调用该接口的相应方法，执行一次同步的通信，传入相应参数，接收相应的返回值。基于此RPC的通信模式，是一个消息拉取的流程，RPC服务器等待RPC客户端的调用，而不会先发制人主动把相关信息推送到RPC客户端去。。。
其实RPC的模式和原理，实在是没啥好说的，之所以说，是因为可以通过把握好这个，彻底理顺Hadoop各服务器间的通信模式。Hadoop会定义一些列的RPC接口，只需要看谁实现，谁调用，就可以知道谁和谁通信，都做些啥事情，图中服务器的基本架构、各服务所使用的协议、调用方向、以及协议中的基本内容。。。

III. 基本的文件操作

基本的文件操作，可以分成两类，一个是对文件目录结构的操作，比如文件和目录的创建、删除、移动、更名等等；另一个是对文件数据流的操作，包括读取和写入文件数据。当然，文件读和写，是有本质区别的，尤其是在数据冗余的情况下，因此，当成两类操作也不足为过。此外，要具体到读写的类别，也是可以再继续分类下去的。在GFS的论文中，对于分布式文件系统的读写场景有一个重要的假定（其实是从实际业务角度得来的...）：就是文件的读取是由大数据量的连续读取和小数据量的随机读取组成，文件的写入则基本上都是批量的追加写，和偶尔的插入写（GFS中还有大量的假设，它们构成了分布式文件系统架构设计的基石。每一个系统架构都是搭建在一定假设上的，这些假设有些来自于实际业务的状况，有些是因为天生的条件约束，不基于假设理解设计，肯定会有失偏颇...）。在GFS中，对文件的写入分成追加写和插入写都有所支持，但是，在HDFS中仅仅支持追加写，这大大降低了复杂性。关于HDFS与GFS的一些不同，可以参看这里。。。
1. 文件和目录的操作
文件目录的信息，全部囤积在主控服务器上，因此，所有对文件目录的操作，只会直接涉及到客户端和主控服务器。整个目录相关的操作流程基本都是这样的：客户端DFSClient调用ClientProtocol定义的相关函数，该操作通过RPC传送到其实现者主控服务器NameNode那里，NameNode做相关的处理后（很少...），调用FSNamesystem的相关函数。在FSNamesystem中，往往是做一些验证和租约操作，具体的目录结构操作交由FSDirectory的相应函数来操作。最后，依次返回，经由RPC传送回客户端。具体各操作涉及到的函数和具体步骤，参见下表：


相关操作 ClientProtocol / NameNode FSNamesystem FSDirectory 关键步骤 
创建文件 create startFile addFile 1. 检查是否有写权限；
2. 检查是否已经存在此文件，如果是覆写，则先进行删除操作；
3. 在指定路径下添加INodeFileUnderConstruction的文件实例；
4. 写日志；
5. 签订租约。 
创建目录 mkdirs mkdirs mkdirs 1. 检查指定目录是否是目录；
2. 检查是否有相关权限；
3. 在指定路径的INode下，添加子节点；
4. 写日志。 
改名操作 rename renameTo renameTo 1. 检查相关路径的权限；
2. 从老路径下移除，在新路径下添加；
3. 修改相关父路径的修改时间；
4. 写日志；
5. 将租约从老路径移动到新路径下。 
删除操作 delete delete delete 1. 如果不是递归删除，确认指定路径是否是空目录；
2. 检查相关权限；
3. 在目录结构上移除相关INode；
4. 修改父路径的修改时间；
5. 将相关的数据块，放入到废弃队列中去，等待处理；
6. 写日志；
7. 废弃相关路径的租约。 
设置权限 setPermission setPermission setPermission 1. 检查owner判断是否有操作权限；
2. 修改指定路径下INode的权限；
3. 写日志。 
设置用户 setOwner setOwner setOwner 1. 检查是否有操作权限；
2. 修改指定路径下INode的权限；
3. 写日志。 
设置时间 setTimes setTimes setTimes 1. 检查是否有写权限；
2. 修改指定路径INode的时间信息；
3. 写日志。 



从上表可以看到，其实有的操作本质上还是涉及到了数据服务器，比如文件创建和删除操作。但是，之前提到，主控服务器只于数据服务器是一个等待拉取的地位，它们不会主动联系数据服务器，将指令传输给它们，而是放到相应的数据结构中，等待数据服务器来取。这样的设计，可以减少通信的次数，加快操作的执行速度。。。
另，上述步骤中，有些日志和租约相关的操作，从概念上来说，和目录操作其实没有任何联系，但是，为了满足分布式系统的需求，这些操作是非常有必要的，在此，按下不表。。。
2、文件的读取
不论是文件读取，还是文件的写入，主控服务器扮演的都是中介的角色。客户端把自己的需求提交给主控服务器，主控服务器挑选合适的数据服务器，介绍给客户端，让客户端和数据服务器单聊，要读要写随你们便。这种策略类似于DMA，降低了主控服务器的负载，提高了效率。。。
因此，在文件读写操作中，最主要的通信，发生在客户端与数据服务器之间。它们之间跑的协议是ClientDatanodeProtocol。从这个协议中间，你无法看到和读写相关的接口，因为，在Hadoop中，读写操作是不走RPC机制的，而是另立门户，独立搭了一套通信框架。在数据服务器一端，DataNode类中有一个DataXceiverServer类的实例，它在一个单独的线程等待请求，一旦接到，就启动一个DataXceiver的线程，处理此次请求。一个请求一个线程，对于数据服务器来说，逻辑上很简单。当下，DataXceiver支持的请求类型有六种，具体的请求包和回复包格式，请参见这里，这里，这里。在Hadoop的实现中，并没有用类来封装这些请求，而是按流的次序写下来，这给代码阅读带来挺多的麻烦，也对代码的维护带来一定的困难，不知道是出于何种考虑。。。
相比于写，文件的读取实在是一个简单的过程。在客户端DFSClient中，有一个DFSClient.DFSInputStream类。当需要读取一个文件的时候，会生成一个DFSInputStream的实例。它会先调用ClientProtocol定义getBlockLocations接口，提供给NameNode文件路径、读取位置、读取长度信息，从中取得一个LocatedBlocks类的对象，这个对象包含一组LocatedBlock，那里面有所规定位置中包含的所有数据块信息，以及数据块对应的所有数据服务器的位置信息。当读取开始后，DFSInputStream会先尝试从某个数据块对应的一组数据服务器中选出一个，进行连接。这个选取算法，在当下的实现中，非常简单，就是选出第一个未挂的数据服务器，并没有加入客户端与数据服务器相对位置的考量。读取的请求，发送到数据服务器后，自然会有DataXceiver来处理，数据被一个包一个包发送回客户端，等到整个数据块的数据都被读取完了，就会断开此链接，尝试连接下一个数据块对应的数据服务器，整个流程，依次如此反复，直到所有想读的都读取完了为止。。。
3、文件的写入
文件读取是一个一对一的过程，一个客户端，只需要与一个数据服务器联系，就可以获得所需的内容。但是，写入操作，则是一个一对多的流程。一次写入，需要在所有存放相关数据块的数据服务器都保持同步的更新，有任何的差池，整个流程就告失败。。。
在分布式系统中，一旦涉及到写入操作，并发处理难免都会沦落成为一个变了相的串行操作。因为，如果不同的客户端如果是任意时序并发写入的话，整个写入的次序无法保证，可能你写半条记录我写半条记录，最后出来的结果乱七八糟不可估量。在HDFS中，并发写入的次序控制，是由主控服务器来把握的。当创建、续写一个文件的时候，该文件的节点类，由INodeFile升级成为INodeFileUnderConstruction，INodeFileUnderConstruction是INodeFile的子类，它起到一个锁的作用。如果当一个客户端想创建或续写的文件是INodeFileUnderConstruction，会引发异常，因为这说明这个此处有爷，请另寻高就，从而保持了并发写入的次序性。同时，INodeFileUnderConstruction有包含了此时正在操作它的客户端的信息以及最后一个数据块的数据服务器信息，当追加写的时候可以更快速的响应。。。
与读取类似，DFSClient也有一个DFSClient.DFSOutputStream类，写入开始，会创建此类的实例。DFSOutputStream会从NameNode上拿一个LocatedBlock，这里面有最后一个数据块的所有数据服务器的信息。这些数据服务器每一个都需要能够正常工作（对于读取，只要还有一个能工作的就可以实现...），它们会依照客户端的位置被排列成一个有着最近物理距离和最小的序列（物理距离，是根据机器的位置定下来的...），这个排序问题类似于著名旅行商问题，属于NP复杂度，但是由于服务器数量不多，所以用最粗暴的算法，也并不会看上去不美。。。
文件写入，就是在这一组数据服务器上构造成数据流的双向流水线。DFSOutputStream，会与序列的第一个数据服务器建立Socket连接，发送请求头，然后等待回应。DataNode同样是建立DataXceiver来处理写消息，DataXceiver会依照包中传过来的其他服务器的信息，建立与下一个服务器的连接，并生成类似的头，发送给它，并等待回包。此流程依次延续，直到最后一级，它发送回包，反向着逐级传递，再次回到客户端。如果一切顺利，那么此时，流水线建立成功，开始正式发送数据。数据是分成一个个数据包发送的，所有写入的内容，被缓存在客户端，当写满64K，会被封装成DFSOutputStream.Packet类实例，放入DFSOutputStream的dataQueue队列。DFSOutputStream.DataStreamer会时刻监听这个队列，一旦不为空，则开始发送，将位于dataQueue队首的包移动到ackQueue队列的队尾，表示已发送但尚未接受回复的包队列。同时启动ResponseProcessor线程监听回包，直到收到相应回包，才将发送包从ackQueue中移除，表示成功。每一个数据服务器的DataXceiver收到了数据包，一边写入到本地文件中去，一边转发给下一级的数据服务器，等待回包，同前面建立流水线的流程。。。
当一个数据块写满了之后，客户端需要向主控服务器申请追加新的数据块。这个会引起一次数据块的分配，成功后，会将新的数据服务器组返还给客户端。然后重新回到上述流程，继续前行。。。
关于写入的流程，还可以参见这里。此外，写入涉及到租约问题，后续会仔细的来说。。。
IV. 分布式支持

如果单机的文件系统是田里勤恳的放牛娃，那么分布式文件系统就是刀尖上讨饭吃的马贼了。在分布式环境中，有太多的意外，数据随时传输错误，服务器时刻准备牺牲，很多平常称为异常的现象，在这里都需要按照平常事来对待。因此，对于分布式文件系统而言，仅仅是满足了正常状况下文件系统各项服务还不够，还需要保证分布式各种意外场景下健康持续的服务，否则，将一无是处。。。
1、服务器的错误恢复
在分布式环境中，哪台服务器牺牲都是常见的事情，牺牲不可怕，可怕的是你都没有时刻准备好它们会牺牲。作为一个合格的分布式系统，HDFS当然时刻准备好了前赴后继奋勇向前。HDFS有三类服务器，每一类服务器出错了，都有相应的应急策略。。。
a. 客户端

生命最轻如鸿毛的童鞋，应该就是客户端了。毕竟，做为一个文件系统的使用者，在整个文件系统中的地位，难免有些归于三流。而作为客户端，大部分时候，牺牲了就牺牲了，没人哀悼，无人同情，只有在在辛勤写入的时候，不幸辞世（机器挂了，或者网络断了，诸如此类...），才会引起些恐慌。因为，此时此刻，在主控服务器上对应的文件，正作为INodeFileUnderConstruction活着，仅仅为占有它的那个客户端服务者，做为一个专一的文件，它不允许别的客户端染指。这样的话，一旦占有它的客户端服务者牺牲了，此客户端会依然占着茅坑不拉屎，让如花似玉INodeFileUnderConstruction孤孤单单守寡终身。这种事情当然无法容忍，因此，必须有办法解决这个问题，办法就是：租约。。。
租约，顾名思义，就是当客户端需要占用某文件的时候，与主控服务器签订的一个短期合同。这个合同有一个期限，在这个期限内，客户端可以延长合同期限，一旦超过期限，主控服务器会强行终止此租约，将这个文件的享用权，分配给他人。。。
在打开或创建一个文件，准备追加写之前，会调用LeaseManager的addLease方法，在指定的路径下与此客户端签订一份租约。客户端会启动DFSClient.LeaseChecker线程，定时轮询调用ClientProtocol的renewLease方法，续签租约。在主控服务器一端，有一个LeaseManager.Monitor线程，始终在轮询检查所有租约，查看是否有到期未续的租约。如果一切正常，该客户端完成写操作，会关闭文件，停止租约，一旦有所意外，比如文件被删除了，客户端牺牲了，主控服务器都会剥夺此租约，如此，来避免由于客户端停机带来的资源被长期霸占的问题。。。
b. 数据服务器

当然，会挂的不只是客户端，海量的数据服务器是一个更不稳定的因素。一旦某数据服务器牺牲了，并且主控服务器被蒙在鼓中，主控服务器就会变相的欺骗客户端，给它们无法连接的读写服务器列表，导致它们处处碰壁无法工作。因此，为了整个系统的稳定，数据服务器必须时刻向主控服务器汇报，保持主控服务器对其的完全了解，这个机制，就是心跳消息。在HDFS中，主控服务器NameNode实现了DatanodeProtocol接口，数据服务器DataNode会在主循环中，不停的调用该协议中的sendHeartbeat方法，向NameNode汇报状况。在此调用中，DataNode会将其整体运行状况告知NameNode，比如：有多少可用空间、用了多大的空间，等等之类。NameNode会记住此DataNode的运行状况，作为新的数据块分配或是负载均衡的依据。当NameNode处理完成此消息后，会将相关的指令封装成一个DatanodeCommand对象，交还给DataNode，告诉数据服务器什么数据块要删除什么数据块要新增等等之类，数据服务器以此为自己的行动依据。。。
但是，sendHeartbeat并没有提供本地的数据块信息给NameNode，那么主控服务器就无法知道此数据服务器应该分配什么数据块应该删除什么数据块，那么它是如何决定的呢？答案就是DatanodeProtocol定义的另一个方法，blockReport。DataNode也是在主循环中定时调用此方法，只是，其周期通常比调用sendHeartbeat的更长。它会提交本地的所有数据块状况给NameNode，NameNode会和本地保存的数据块信息比较，决定什么该删除什么该新增，并将相关结果缓存在本地对应的数据结构中，等待此服务器再发送sendHeartbeat消息过来的时候，依照这些数据结构中的内容，做出相应的DatanodeCommand指令。blockReport方法同样也会返回一个DatanodeCommand给DataNode，但通常，只是为空（只有出错的时候不为空），我想，增加缓存，也许是为了确保每个指令都可以重复发送并确定被执行。。。
c. 主控服务器

当然，作为整个系统的核心和单点，含辛茹苦的主控服务器含泪西去，整个分布式文件服务集群将彻底瘫痪罢工。如何在主控服务器牺牲后，提拔新的主控服务器并迅速使其进入工作角色，就成了系统必须考虑的问题。解决策略就是：日志。。。
其实这并不是啥新鲜东西，一看就知道是从数据库那儿偷师而来的。在主控服务器上，所有对文件目录操作的关键步骤（具体文件内容所处的数据服务器，是不会被写入日志的，因为这些内容是动态建立的...），都会被写入日志。另外，主控服务器会在某些时刻，将当下的文件目录完整的序列化到本地，这称为镜像。一旦存有镜像，镜像前期所写的日志和其他镜像，都纯属冗余，其历史使命已经完成，可以报废删除了。在主控服务器不幸牺牲，或者是战略性的停机修整结束，并重新启动后，主控服务器会根据最近的镜像 + 镜像之后的所有日志，重建整个文件目录，迅速将服务能力恢复到牺牲前的水准。。。
对于数据服务器而言，它们会通过一些手段，迅速得知顶头上司的更迭消息。它们会立刻转投新东家的名下，在新东家旗下注册，并开始向其发送心跳消息，这个机制，可能用分布式协同服务来实现，这里不说也罢。。。
在HDFS的实现中，FSEditLog类是整个日志体系的核心，提供了一大堆方便的日志写入API，以及日志的恢复存储等功能。目前，它支持若干种日志类型，都冠以OP_XXX，并提供相关API，具体可以参见这里。为了保证日志的安全性，FSEditLog提供了EditLogFileOutputStream类作为写入的承载类，它会同时开若干个本地文件，然后依次写入，防止日志的损坏导致不可估量的后果。在FSEditLog上面，有一个FSImage类，存储文件镜像并调用FSEditLog对外提供相关的日志功能。FSImage是Storage类的子类，如果对数据块的讲述有所印象的话，你可以回忆起来，凡事从此类派生出来的东西，都具有版本性质，可以进行升级和回滚等等，以此，来实现产生镜像是对原有日志和镜像处理的复杂逻辑。。。
目前，在HDFS的日志系统中，有些地方与GFS的描述有所不同。在HDFS中，所有日志文件和镜像文件都是本地文件，这就相当于，把日志放在自家的保险箱中，一旦主控服务器挂了，别的后继而上的服务器也无法拿到这些日志和镜像，用于重振雄风。因此，在HDFS中，运行着一个SecondaryNameNode服务器，它做为主控服务器的替补，隐忍厚积薄发为篡位做好准备，其中，核心内容就是：定期下载并处理日志和镜像。SecondaryNameNode看上去像客户端一样，与NameNode之间，走着NamenodeProtocol协议。它会不停的查看主控服务器上面累计日志的大小，当达到阈值后，调用doCheckpoint函数，此函数的主要步骤包括：
首先是调用startCheckpoint做一些本地的初始化工作；

然后调用rollEditLog，将NameNode上此时操作的日志文件从edit切到edit.new上来，这个操作瞬间完成，上层写日志的函数完全感觉不到差别；

接着，调用downloadCheckpointFiles，将主控服务器上的镜像文件和日志文件都下载到此候补主控服务器上来；

并调用doMerge，打开镜像和日志，将日志生成新的镜像，保存覆盖；

下一步，调用putFSImage把新的镜像上传回NameNode；

再调用rollFsImage，将镜像换成新的，在日志从edit.new改名为edit；

最后，调用endCheckpoint做收尾工作。

整个算法涉及到NameNode和SecondaryNameNode两个服务器，最终结果是NameNode和SecondaryNameNode都依照算法进行前的日志生成了镜像。而两个服务器上日志文件的内容，前者是整个算法进行期间所写的日志，后者始终不会有任何日志。当主控服务器牺牲的时候，运行SecondaryNameNode的服务器立刻被扶正，在其上启动主控服务，利用其日志和镜像，恢复文件目录，并逐步接受各数据服务器的注册，最终向外提供稳定的文件服务。。。
同样的事情，GFS采用的可能是另外一个策略，就是在写日志的时候，并不局限在本地，而是同时书写网络日志，即在若干个远程服务器上生成同样的日志。然后，在某些时机，主控服务器自己，生成镜像，降低日志规模。当主控服务器牺牲，可以在拥有网络日志的服务器上启动主控服务，升级成为主控服务器。。。
GFS与HDFS的策略相比较，前者是化整为零，后者则是批量处理，通常我们认为，批量处理的平均效率更高一些，且相对而言，可能实现起来容易一些，但是，由于有间歇期，会导致日志的丢失，从而无法100%的将备份主控服务器的状态与主控服务器完全同步。。。
2、数据的正确性保证

在复杂纷繁的分布式环境中，我们坚定的相信，万事皆有可能。哪怕各个服务器都舒舒服服的活着，也可能有各种各样的情况导致网络传输中的数据丢失或者错误。并且在分布式文件系统中，同一份文件的数据，是存在大量冗余备份的，系统必须要维护所有的数据块内容完全同步，否则，一人一言，不同客户端读同一个文件读出不同数据，用户非得疯了不可。。。
在HDFS中，为了保证数据的正确性和同一份数据的一致性，做了大量的工作。首先，每一个数据块，都有一个版本标识，在Block类中，用一个长整型的数generationStamp来表示版本信息（Block类是所有表示数据块的数据结构的基类），一旦数据块上的数据有所变化，此版本号将向前增加。在主控服务器上，保存有此时每个数据块的版本，一旦出现数据服务器上相关数据块版本与其不一致，将会触发相关的恢复流程。这样的机制保证了各个数据服务器器上的数据块，在基本大方向上都是一致的。但是，由于网络的复杂性，简单的版本信息无法保证具体内容的一致性（因为此版本信息与内容无关，可能会出现版本相同，但内容不同的状况）。因此，为了保证数据内容上的一致，必须要依照内容，作出签名。。。
当客户端向数据服务器追加写入数据包时，每一个数据包的数据，都会切分成512字节大小的段，作为签名验证的基本单位，在HDFS中，把这个数据段称为Chunk，即传输块（注意，在GFS中，Chunk表达的是数据块...）。在每一个数据包中，都包含若干个传输块以及每一个传输块的签名，当下，这个签名是根据Java SDK提供的CRC算法算得的，其实就是一个奇偶校验。当数据包传输到流水线的最后一级，数据服务器会对其进行验证（想一想，为什么只在最后一级做验证，而不是每级都做...），一旦发现当前的传输块签名与在客户端中的签名不一致，整个数据包的写入被视为无效，Lease Recover（租约恢复）算法被触发。。。
从基本原理上看，这个算法很简单，就是取所有数据服务器上此数据块的最小长度当作正确内容的长度，将其他数据服务器上此数据块超出此长度的部分切除。从正确性上看，此算法无疑是正确的，因为至少有一个数据服务器会发现此错误，并拒绝写入，那么，如果写入了的，都是正确的；从效率上看，此算法也是高效的，因为它避免了重复的传输和复杂的验证，仅仅是各自删除尾部的一些内容即可。但从具体实现上来看，此算法稍微有些绕，因为，为了降低本已不堪重负的主控服务器的负担，此算法不是由主控服务器这个大脑发起的，而是通过选举一个数据服务器作为Primary，由Primary发起，通过调用与其他各数据服务器间的InterDatanodeProtocol协议，最终完成的。具体的算法流程，参见LeaseManager类上面的注释。需要说明的是此算法的触发时机和发起者。此算法可以由客户端或者是主控服务器发起，当客户端在写入一个数据包失败后，会发起租约恢复。因为，一次写入失败，不论是何种原因，很有可能就会导致流水线上有的服务器写了，有的没写，从而造成不统一。而主控服务器发起的时机，则是在占有租约的客户端超出一定时限没有续签，这说明客户端可能挂了，在临死前可能干过不利于数据块统一的事情，作为监督者，主控服务器需要发起一场恢复运动，确保一切正确。。。
3、负载均衡

负载的均衡，是分布式系统中一个永恒的话题，要让大家各尽其力齐心干活，发挥各自独特的优势，不能忙得忙死闲得闲死，影响战斗力。而且，负载均衡也是一个复杂的问题，什么是均衡，是一个很模糊的概念。比如，在分布式文件系统中，总共三百个数据块，平均分配到十个数据服务器上，就算均衡了么？其实不一定，因为每一个数据块需要若干个备份，各个备份的分布应该充分考虑到机架的位置，同一个机架的服务器间通信速度更快，而分布在不同机架则更具有安全性，不会在一棵树上吊死。。。
在这里说的负载均衡，是宽泛意义上的均衡过程，主要涵盖两个阶段的事务，一个是在任务初始分配的时候尽可能合理分配，另一个是在事后时刻监督及时调整。。。
在HDFS中，ReplicationTargetChooser类，是负责实现为新分配的数据块寻找婆家的。基本上来说，数据块的分配工作和备份的数量、申请的客户端地址（也就是写入者）、已注册的数据服务器位置，密切相关。其算法基本思路是只考量静态位置信息，优先照顾写入者的速度，让多份备份分配到不同的机架去。具体算法，自行参见源码。此外，HDFS的Balancer类，是为了实现动态的负载调整而存在的。Balancer类派生于Tool类，这说明，它是以一个独立的进程存在的，可以独立的运行和配置。它运行有NamenodeProtocol和ClientProtocol两个协议，与主控服务器进行通信，获取各个数据服务器的负载状况，从而进行调整。主要的调整其实就是一个操作，将一个数据块从一个服务器搬迁到另一个服务器上。Balancer会向相关的目标数据服务器发出一个DataTransferProtocol.OP_REPLACE_BLOCK消息，接收到这个消息的数据服务器，会将数据块写入本地，成功后，通知主控服务器，删除早先的那个数据服务器上的同一块数据块。具体的算法请自行参考源码。。。
4、垃圾回收
对于垃圾，大家应该耳熟能详了，在分布式文件系统而言，没有利用价值的数据块备份，就是垃圾。在现实生活中，我们提倡垃圾分类，为了更好的理解分布式文件系统的垃圾收集，搞个分类也是很有必要的。基本上，所有的垃圾都可以视为两类，一类是由系统正常逻辑产生的，比如某个文件被删除了，所有相关的数据块都沦为垃圾了，某个数据块被负载均衡器移动了，原始数据块也不幸成了垃圾了。此类垃圾最大的特点，就是主控服务器是生成垃圾的罪魁祸首，也就是说主控服务器完全了解有哪些垃圾需要处理。另外还有一类垃圾，是由于系统的一些异常症状产生的，比如某个数据服务器停机了一段，重启之后发现其上的某个数据块已经在其他服务器上重新增加了此数据块的备份，它上面的那个备份过期了失去价值了，需要被当作垃圾来处理了。此类垃圾的特点恰恰相反，主控服务器无法直接了解到垃圾状况，需要曲线救国。。。
在HDFS中，第一类垃圾的判定自然很容易，在一些正常的逻辑中产生的垃圾，全部被塞进了FSNamesystem的recentInvalidateSets这个Map中。而第二类垃圾的判定，则放在数据服务器发送其数据块信息来的过程中，经过与本地信息的比较，可以断定，此数据服务器上有哪些数据块已经不幸沦为垃圾。同样，这些垃圾也被塞到recentInvalidateSets中去。在与数据服务器进行心跳交流的过程中，主控服务器会将它上面有哪些数据块需要删除，数据服务器对这些数据块的态度是，直接物理删除。在GFS的论文中，对如何删除一个数据块有着不同的理解，它觉着应该先缓存起来，过几天没人想恢复它了再删除。在HDFS的文档中，则明确表示，在现行的应用场景中，没有需要这个需求的地方，因此，直接删除就完了。这说明，理念是一切分歧的根本：）。。。
V. 总结

整个分布式文件系统，计算系统，数据库系统的设计理念，基本是一脉相承的。三类服务器、作为单点存在的核心控制服务器、基于日志的恢复机制、基于租约的保持联系机制、等等，在后续分布式计算系统和分布式数据库中都可以看到类似的影子，在分布式文件系统这里，我详述了这些内容，可能在后续就会默认知道而说的比较简略了。而刨去这一些，分布式文件系统中最大特点，就是文件块的冗余存储，它直接导致了较为复杂的写入流程。当然，虽说分布式文件系统在分布式计算和数据库中都有用到，但如果对其机理没有兴趣，只要把它当成是一个可以在任何机器上使用的文件系统，就不会对其他上层建筑的理解产生障碍。。。]]></description></item><item><link>http://h31home.com/h312005/blogview.asp?ID=997</link><title><![CDATA[VC进程间通信消息]]></title><author>admin</author><category>VC学习</category><pubDate>2009-2-3 17:13:07</pubDate><guid>http://h31home.com/h312005/blogview.asp?ID=997</guid><description><![CDATA[进程间通信
void CH31Connect1Dlg::OnOK() 
{
CWnd *pCwnd； 
//用FindWindow函数找到想要关闭的应用程序的句柄的指针 
pCwnd=FindWindow(NULL,"H31CONNECT2")； 
//如果返回成功 
CString str="sendisok"；
COPYDATASTRUCT aa；
aa.dwData=1；
aa.cbData=str.GetLength()+1；
//memcpy(aa.lpData,str,aa.cbData)；
aa.lpData = (void*)str.GetBuffer(aa.cbData)；
if( pCwnd )
::SendMessage(pCwnd->m_hWnd,WM_COPYDATA,(WPARAM)this->m_hWnd,(LPARAM)&aa)；//给其发送关闭的消息 
}
程序2添加OnCopyData事件
BOOL CH31Connect2Dlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 
{
// TODO: Add your message handler code here and/or call default
CString aa = (LPCSTR)(pCopyDataStruct->lpData)； 
AfxMessageBox(aa)；
//return CDialog::OnCopyData(pWnd, pCopyDataStruct)；
return true；
}]]></description></item><item><link>http://h31home.com/h312005/blogview.asp?ID=996</link><title><![CDATA[C#测试委托+观察者模式]]></title><author>admin</author><category>VS and C#</category><pubDate>2008-12-5 11:22:43</pubDate><guid>http://h31home.com/h312005/blogview.asp?ID=996</guid><description><![CDATA[using System；
using System.Collections.Generic；
using System.Text；
namespace ConsoleApplication1
{
      class Program
    {
        
        static void Main(string[] args)
        {
    //测试委托+观察者模式
            HBoss aa = new HBoss()；
            HObserver bb = new HObserver("XXXX", aa)；
            aa.Update += new EventHandler(bb.CloseStock)；
            aa.SubjectState = "Boss comeback.."；
            aa.Notify()；
        }
    }
    interface Subject
    {
        void Notify()；
        string SubjectState
        {
            get；
            set；
        }
    }
    class HObserver
    {
        private string name；
        private Subject sub；
        public HObserver(string name,Subject sub)
        {
            this.name = name；
            this.sub = sub；
        }
        public void CloseStock()
        {
            Console.WriteLine("{0},{1}关闭股票行情，继续工作", sub.SubjectState,name)；
        }
    }
    delegate void EventHandler()；
    class HBoss:Subject
    {
        public event EventHandler Update；
        private string action；
        public void Notify()
        {
            Update()；
        }
        public string SubjectState
        {
            get { return action； }
            set { action = value； }
        }
    }；
}
--------------------------------------------
using System；
using System.Collections.Generic；
using System.Text；
namespace ConsoleApplication1
{
     public class A   
    {   
        public A()   
        {   
        Console.WriteLine('A')；   
        }   
        public virtual void Fun()   
        {   
        Console.WriteLine("A.Fun()")；   
        }   
    }
    public class B : A
    {
        public B()
        {
            Console.WriteLine('B')；
        }
        public new void Fun()
        {
            Console.WriteLine("B.Fun()")；
        }
    }
    class Class1 
    { 
        public static int Count = 0； 
        static Class1() 
        { 
        Count++； 
        } 
        public Class1() 
        { 
        Count++； 
        } 
    } 
    class Program
    {
        
        static void Main(string[] args)
        {
            //A a = new B()；   
            //a.Fun()；
            //Class1 o1 = new Class1()；
            //Class1 o2 = new Class1()； 
   //输出A         B           A.Fun()

        }
    }
 
}]]></description></item><item><link>http://h31home.com/h312005/blogview.asp?ID=995</link><title><![CDATA[DataTable使用技巧总结 ]]></title><author>admin</author><category>VS and C#</category><pubDate>2008-9-25 9:32:23</pubDate><guid>http://h31home.com/h312005/blogview.asp?ID=995</guid><description><![CDATA[       在项目中经常用到DataTable,如果DataTable使用得当，不仅能使程序简洁实用，而且能够提高性能，达到事半功倍的效果，现对DataTable的使用技巧进行一下总结。 


        一、DataTable简介     

          (1)构造函数 
          DataTable()   不带参数初始化DataTable 类的新实例。 
          DataTable(string tableName)  用指定的表名初始化DataTable 类的新实例。 
          DataTable(string tableName, string tableNamespace) 用指定的表名和命名空间初始化DataTable 类的新实例。 
          (2) 常用属性 
          CaseSensitive    指示表中的字符串比较是否区分大小写。 
          ChildRelations   获取此DataTable 的子关系的集合。 
          Columns             获取属于该表的列的集合。 
          Constraints        获取由该表维护的约束的集合。 
          DataSet               获取此表所属的DataSet。DataSet相关信息，可见我以前的一篇文章《数据访问(2)－DataSet》 
          DefaultView       获取可能包括筛选视图或游标位置的表的自定义视图。 
          HasErrors          获取一个值，该值指示该表所属的DataSet 的任何表的任何行中是否有错误。 
          MinimumCapacity  获取或设置该表最初的起始大小。该表中行的最初起始大小。默认值为 50。 
          Rows                  获取属于该表的行的集合。 
          TableName       获取或设置DataTable 的名称。 


          (3)常用方法 
          AcceptChanges()   提交自上次调用AcceptChanges() 以来对该表进行的所有更改。 
          BeginInit()         开始初始化在窗体上使用或由另一个组件使用的DataTable。初始化发生在运行时。 

          Clear()               清除所有数据的DataTable。 
          Clone()              克隆DataTable 的结构，包括所有DataTable 架构和约束。 
          EndInit()            结束在窗体上使用或由另一个组件使用的DataTable 的初始化。初始化发生在运行时。 
          ImportRow(DataRow row)    将DataRow 复制到DataTable 中，保留任何属性设置以及初始值和当前值。 
          Merge(DataTable table)  将指定的DataTable 与当前的DataTable 合并。 
          NewRow()         创建与该表具有相同架构的新DataRow。
 
        二、DataTable使用技巧

      （1）Create a DataTable
         DataTable dt = new DataTable("Table_AX")； 


      （2）Add columns for DataTable
        //Method 1
        dt.Columns.Add("column0", System.Type.GetType("System.String"))；
        //Method 2
        DataColumn dc = new DataColumn("column1", System.Type.GetType("System.Boolean"))；
        dt.Columns.Add(dc)； 

       （3）Add rows for DataTable
         //Initialize the row
         DataRow dr = dt.NewRow()；
         dr["column0"] = "AX"；
         dr["column1"] = true；
         dt.Rows.Add(dr)；
         //Doesn't initialize the row
         DataRow dr1 = dt.NewRow()；
         dt.Rows.Add(dr1)；  


        （4）Ｓelect row
         //Search the second row 如果没有赋值,则用is null来Ｓelect
         DataRow[] drs = dt.Ｓelect("column1 is null")；
         DataRow[] drss = dt.Ｓelect("column0 = 'AX'")； 


        （5）Copy DataTable include data
         DataTable dtNew = dt.Copy()； 

        （6）Copy DataTable only scheme
         DataTable dtOnlyScheme = dt.Clone()； 

        （7）Operate one row
         //对dt的操作
         //Method 1
         DataRow drOperate = dt.Rows[0]；
         drOperate["column0"] = "AXzhz"；
         drOperate["column1"] = false；
         //Method 2
         drOperate[0] = "AXzhz"；
         drOperate[1] = false；
         //Method 3
         dt.Rows[0]["column0"] = "AXzhz"；
         dt.Rows[0]["column1"] = false；
         //Method 4
         dt.Rows[0][0] = "AXzhz"；
         dt.Rows[0][1] = false； 

       （8）Evaluate another DataTable's row to current Datatable
         dtOnlyScheme.Rows.Add(dt.Rows[0].ItemArray)； 

       （9）Convert to string
         System.IO.StringWriter sw = new System.IO.StringWriter()；
         System.Xml.XmlTextWriter xw = new System.Xml.XmlTextWriter(sw)；
         dt.WriteXml(xw)；
         string s = sw.ToString()；

        （10）Filter DataTable
         dt.DefaultView.RowFilter = "column1 <> true"；
         dt.DefaultView.RowFilter = "column1 = true"；

        （11）Sort row
          dt.DefaultView.Sort = "ID ,Name ASC"；
          dt=dt.DefaultView.ToTable()；

         （12）Bind DataTable
           //绑定的其实是DefaultView
          gvTestDataTable.DataSource = dt；
          gvTestDataTable.DataBind()；

         （13）judge the DataTable’s Column name is a string
          //判断一个字符串是否为DataTable的列名
         dtInfo.Columns.Contains("AX")；

         （14）DataTable convert to XML and XML convert to DataTable
          protected void Page_Load(object sender, EventArgs e)
          {
             DataTable dt_AX = new DataTable()； 
             //dt_AX.Columns.Add("Sex", typeof(System.Boolean))；
             //DataRow dr = dt_AX.NewRow()；
             //dr["Sex"] = true；
             //dt_AX.Rows.Add(dr)； 
             string xml=ConvertBetweenDataTableAndXML_AX(dt_AX)；
             DataTable dt = ConvertBetweenDataTableAndXML_AX(xml)；
         } 
         public string ConvertBetweenDataTableAndXML_AX(DataTable dtNeedCoveret)
        {
             System.IO.TextWriter tw = new System.IO.StringWriter()；
             //if TableName is empty, WriteXml() will throw Exception.                  

dtNeedCoveret.TableName=dtNeedCoveret.TableName.Length==0?"Table_AX":dtNeedCoveret.TableName；
             dtNeedCoveret.WriteXml(tw)；
             dtNeedCoveret.WriteXmlSchema(tw)；
             return tw.ToString()；
        } 
         public DataTable ConvertBetweenDataTableAndXML_AX(string xml)
        {
             System.IO.TextReader trDataTable = new System.IO.StringReader(xml.Substring(0, xml.IndexOf("<?xml")))；
             System.IO.TextReader trSchema = new System.IO.StringReader(xml.Substring(xml.IndexOf("<?xml")))；
             DataTable dtReturn = new DataTable()；
             dtReturn.ReadXmlSchema(trSchema)；
             dtReturn.ReadXml(trDataTable)；
             return dtReturn；
        }

]]></description></item><item><link>http://h31home.com/h312005/blogview.asp?ID=994</link><title><![CDATA[SqlServer存储过程之简单入门 ]]></title><author>admin</author><category>Oralce</category><pubDate>2008-9-25 9:30:30</pubDate><guid>http://h31home.com/h312005/blogview.asp?ID=994</guid><description><![CDATA[一、简单实例

1.首先来一个最简单的存储过程吧
CREATE PROCEDURE dbo.testProcedure_AX
AS
Ｓelect userID from USERS order by userid desc
注:dbo.testProcedure_AX是你创建的存储过程名,可以改为:AXzhz等,别跟关键字冲突就行了,AS下面就是一条SQL语句.


2.如何在ASP.NET中调用这个存储过程?
        public static string GetCustomerCName(ref ArrayList arrayCName,ref ArrayList arrayID)
        {
            SqlConnection con=ADConnection.createConnection()；
            SqlCommand cmd=new SqlCommand("testProcedure_AX",con)；
            cmd.CommandType=CommandType.StoredProcedure；
            con.Open()；
            try
            {
                SqlDataReader dr=cmd.ExecuteReader()；
                while(dr.Read())
                {
                    if(dr[0].ToString()=="")
                    {
                        arrayCName.Add(dr[1].ToString())；
                    }
                }
                con.Close()； 
                return "OK!"；
            }
            catch(Exception ex)
            {
                con.Close()；
                return ex.ToString()；
            }
        }
注:其实就是把以前
SqlCommand cmd=new SqlCommand("Ｓelect userID from USERS order by userid desc",con)；
中的SQL语句替换为存储过程名,再把cmd的类型标注为CommandType.StoredProcedure(存储过程)


3.再来个带参数的存储过程吧.
CREATE PROCEDURE dbo.AXzhz
/*
这里写注释
*/
@startDate varchar(16),
@endDate varchar(16) 
AS
 Ｓelect id  from table_AX where commentDateTime>@startDate and commentDateTime<@endDate order by contentownerid DESC

注:@startDate varchar(16)是声明@startDate 这个变量,多个变量名间用【,】隔开.后面的SQL就可以使用这个变量了.


4.如何在ASP.NET中调用这个带参数的存储过程?
 public static string GetCustomerCNameCount(string startDate,string endDate,ref DataSet ds)
{
            SqlConnection con=ADConnection.createConnection()；
//-----------------------注意这一段--------------------------------------------------------------------------
            SqlDataAdapter da=new SqlDataAdapter("AXzhz",con)；

            para0=new SqlParameter("@startDate",startDate)；
            para1=new SqlParameter("@endDate",endDate)；
            da.ＳelectCommand.Parameters.Add(para0)；
            da.ＳelectCommand.Parameters.Add(para1)；
            da.ＳelectCommand.CommandType=CommandType.StoredProcedure；
//-----------------------------------------------------------------------------------------------------------
            try
            {
                con.Open()；
                da.Fill(ds)；
                con.Close()；
                return "OK"；
            }
            catch(Exception ex)
            {
                return ex.ToString()；
            }            
        }

注:把命令的参数添加进去,就OK了.

5.如何查看SQL命令执行成功了没有.
CREATE PROCEDURE dbo.AXzhz
/*
  @parameter1 用户名
  @parameter2 新密码
*/
@password nvarchar(20),
@userName nvarchar(20)
AS
declare @err0 int
update WL_user set password=@password where UserName=@userName
set @err0=@@error 
Ｓelect  @err0 as err0

注:先声明一个整型变量@err0,再给其赋值为@@error(这个是系统自动给出的语句是否执行成功,0为成功,其它为失败),最后通过Ｓelect把它选择出来.


6.如何从后台获得这个执行成功与否的值?
下面这段代码可以告诉你答案:
    public static string GetCustomerCName()
        {
            SqlConnection con=ADConnection.createConnection()；            
            SqlCommand cmd=new SqlCommand("AXzhz",con)；
            cmd.CommandType=CommandType.StoredProcedure；
            para0=new SqlParameter("@startDate","2006-9-10")；
            para1=new SqlParameter("@endDate","2006-9-20")；
            da.ＳelectCommand.Parameters.Add(para0)；
            da.ＳelectCommand.Parameters.Add(para1)； 
            con.Open()；
            try
            {
               Int32 re=(int32)cmd.ExecuteScalar()； 
                con.Close()； 
                if (re==0)
                 return "OK!"；
                else
                 return "false"；
            }
            catch(Exception ex)
            {
                con.Close()；
                return ex.ToString()；
            }
        }

7.如何根据传入的参数判断执行哪条SQL语句?
ALTER PROCEDURE dbo.ＳelectCustomerCNameCount
@customerID int
AS
if @customerID=-1
 begin
 Ｓelect contentownerid ,userCName,count(*) as countAll from view_usercomment group by contentownerid,userCName order by contentownerid DESC
 end
else
 begin
 Ｓelect contentownerid ,userCName,count(*) as countAll from view_usercomment where contentownerid=@customerID group by contentownerid,userCName order by contentownerid DESC
 end

二、C＃中使用带返回值的存储过程

例如在向数据库添加新数据时，需要检测是否有重复
本例介绍如何把这个检测的过程放在存储过程中，并用程序调用检测的结果做出反应。
存储过程如下：
CREATE PROCEDURE DInstitute_Insert
@InstituteNO nvarchar(6),@InstituteName nvarchar(40)
 AS
declare @return int,@count int
if(ltrim(rtrim(@InstituteName))='' or ltrim(rtrim(@InstituteNO))='')
 Ｓelect @return=3--返回3表示提交的数据有空值
else
begin
 Ｓelect @count=count(1) from DInstitute where InstituteNO=@InstituteNO
 if(@count>0)
  Ｓelect @return=1--返回1表示编号有重复
 else
 begin 
  insert into DInstitute (InstituteNO,InstituteName) values  (@InstituteNO,@InstituteName) 
  if(@@error>0)
   Ｓelect @return=2--返回2表示数据操作错误
  else
   Ｓelect @return=0--返回0表示数据操作成功
 end
end
return @return
GO 

其中DInstitute 是一个学院信息表。只有InstituteNO（学院编号）、InstituteName（学院名称）两个字段。

在C＃中调用本存储过程的代码如下：
//执行插入操作
            SqlCommand com1 = new SqlCommand("DInstitute_Insert", DBcon)；
            if (com1.Connection.State == ConnectionState.Closed)
                com1.Connection.Open()；
            com1.CommandType = CommandType.StoredProcedure；
            com1.Parameters.Add(new SqlParameter("@InstituteNO",SqlDbType.NVarChar,6))；
            com1.Parameters.Add(new SqlParameter("@InstituteName", SqlDbType.NVarChar, 40))；
            com1.Parameters.Add(new SqlParameter("@return", SqlDbType.Int))；
            com1.Parameters["@return"].Direction = ParameterDirection.Returnvalue；
            com1.Parameters["@InstituteNO"].value = t_NO.Text；
            com1.Parameters["@InstituteName"].value = t_name.Text；
            try
            {
                com1.ExecuteScalar()；
            }
            catch(SqlException ee)
            {
                DB.msgbox("操作失败！"+ee.Message.ToString())；
                return；
            }
            finally
            {
                com1.Connection.Close()；
            }
            string temp = com1.Parameters["@return"].value.ToString()；
            //返回0表示数据操作成功
            //返回1表示编号有重复   
            //返回2表示数据操作错误 
            //返回3表示提交的数据有空值
            switch (temp)
            {
                case "0":
                    DB.msgbox("添加成功！")；
                    break；
                case "1":
                    DB.msgbox("编号有重复！")；
                    break；
                case "2":
                    DB.msgbox("数据操作错误！")；
                    break；
                case "3":
                    DB.msgbox("提交的数据有空值！")；
                    break；
            }
            Binding()； //刷新datagrid 

三、SqlServer存储过程的事务处理

方法一：
--测试的表   
  create   table   tb(  id   int     not   null     constraint   PK_sys_zj_fielddict   primary   key   ,aa   int)   
  --事务处理   
  begin   tran   
  insert   into   tb   values(1,1)   
  if   @@error<>0   goto   lb_rollback   
  insert   into   tb   values(1,1)   
  if   @@error<>0   goto   lb_rollback   
  insert   into   tb   values(2,1)   
  if   @@error<>0   goto   lb_rollback   
  insert   into   tb   values(2,1)   
  if   @@error<>0   goto   lb_rollback   
  insert   into   tb   values(3,1)   
  if   @@error<>0   goto   lb_rollback   
  lb_commit:   
  commit   tran   
  goto   lb_ok   
  lb_rollback:   
  rollback   tran       
  --显示结果   
  lb_ok:   
  Ｓelect   *   from   tb   
  drop   table   tb


方法二：
--创建测试表   
  create   table   tb(id   int     not   null     constraint   PK_sys_zj_fielddict   primary   key  ,aa   int)       
  --设置选项   
  SET   XACT_ABORT   on       
  --事务处理   
  begin   tran   
  insert   into   tb   values(1,1)   
  insert   into   tb   values(1,1)   
  insert   into   tb   values(2,1)   
  commit   tran       
  --显示结果   
  /*--------注意   
          如果这样写的话,后面的语句不会被执行,如果要执行后面的语句,要在这句后面加上GO,仅查询分析分析器支持,所以如果是在存储过程中,要保证commit   tran后面没有其他语句,否则出错时,其他语句不会被执行   
  -----------*/   
  Ｓelect   *   from   tb   
  drop   table   tb   

四、.Net中使用事务处理


SqlConnection myConnection = new SqlConnection("Data Source=localhost；Initial Catalog=Northwind；Integrated Security=SSPI；")； 
myConnection.Open()； 

SqlTransaction myTrans = myConnection.BeginTransaction()； //使用New新生成一个事务 
SqlCommand myCommand = new SqlCommand()； 
myCommand.Transaction = myTrans； 

try 
{ 
myCommand.CommandText = "Update Address set location='23 rain street' where userid='0001'"； 
myCommand.ExecuteNonQuery()； 

myCommand.CommandText = "Update table2 set dd='23 rain street' where userid='0001'"； 
myCommand.ExecuteNonQuery()； 

myTrans.Commit()； 
Console.WriteLine("Record is udated.")； 
} 
catch(Exception e) 
{ 
myTrans.Rollback()； 
Console.WriteLine(e.ToString())； 
Console.WriteLine("Sorry, Record can not be updated.")； 
} 
finally 
{ 
myConnection.Close()； 
}

说明：在SqlServer中，每条Sql语句都作为一个事务来执行，所以无论在存储过程，还是在.net代码中使用，执行单条Sql语句没有必要使用事务处理。

信息来源：http://www.cnblogs.com/tuyile006/

]]></description></item><item><link>http://h31home.com/h312005/blogview.asp?ID=993</link><title><![CDATA[C#中取得程序當前工作目錄和執行目錄的一些方法 ]]></title><author>admin</author><category>VS and C#</category><pubDate>2008-9-20 8:44:26</pubDate><guid>http://h31home.com/h312005/blogview.asp?ID=993</guid><description><![CDATA[总结C#中得到程序当前工作目录和执行目录的一些方法 

1.   System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName
     获取模块的完整路径。
2.   System.Environment.CurrentDirectory
     获取和设置当前目录(该进程从中启动的目录)的完全限定目录。
3.   System.IO.Directory.GetCurrentDirectory() 
     获取应用程序的当前工作目录。这个不一定是程序从中启动的目录啊，有可能程序放在C:\www里,这个函数有可能返回C:\Documents and Settings\ZYB\,或者C:\Program Files\Adobe\,有时不一定返回什么东东，我也搞不懂了。
4.  System.AppDomain.CurrentDomain.BaseDirectory
     获取程序的基目录。
5.  System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase
     获取和设置包括该应用程序的目录的名称。
6.  System.Windows.Forms.Application.StartupPath 
     获取启动了应用程序的可执行文件的路径。效果和2、5一样。只是5返回的字符串后面多了一个"\"而已
7.  System.Windows.Forms.Application.ExecutablePath
     获取启动了应用程序的可执行文件的路径及文件名，效果和1一样。

8.进程对象在.NET中表现为System.Diagnostics.Process类，通过调用Process.GetCurrentProcess().MainModule.FileName可获得当前执行的exe的文件名。


//正在运行的程序路径和文件名 
string _file = Application.ExecutablePath；
//正在运行的程序路径 
string _path = Application.StartupPath；
//正在运行的程序名称 
string _name = _file.Replace(string.Format("{0}\\", _path), string.Empty)； 
]]></description></item><item><link>http://h31home.com/h312005/blogview.asp?ID=992</link><title><![CDATA[如何將程序的Access数据库嵌入到资源中发布 ]]></title><author>admin</author><category>VS and C#</category><pubDate>2008-9-20 8:42:19</pubDate><guid>http://h31home.com/h312005/blogview.asp?ID=992</guid><description><![CDATA[ 1        private string AccessPath = Application.StartupPath.ToString() + "\\" + "SAP_Words.dll"；
 2        private string ResourcesPath = Application.StartupPath.ToString() + "\\" + "Resources.dll"；
 3
 4       調用 WriteEmbeddedFile("SAP_Words.dll", AccessPath)；
 5        private Stream GetStream(string name)
 6        {
 7            return GetResourceAssembly().GetManifestResourceStream("資源類的命名空間."+name)；
 8        }
 9
10        private Assembly GetResourceAssembly()
11        {
12            return Assembly.LoadFrom(ResourcesPath)；
13        }
14
15        private void WriteEmbeddedFile(string name, string fileName)
16        {
17            using (Stream stream = GetStream(name))
18            {
19                FileInfo file = new FileInfo(fileName)；
20                using (FileStream fileStream = file.Create())
21                {
22                    byte[] buf = new byte[1024]；
23                    int size；
24                    while ((size = stream.Read(buf, 0, 1024)) > 0)
25                    {
26                        fileStream.Write(buf, 0, size)；
27                    }
28                }
29            }
30        }
]]></description></item><item><link>http://h31home.com/h312005/blogview.asp?ID=991</link><title><![CDATA[用反射方法使用户控件动态调用父页面的方法 ]]></title><author>admin</author><category>VS and C#</category><pubDate>2008-9-20 8:41:32</pubDate><guid>http://h31home.com/h312005/blogview.asp?ID=991</guid><description><![CDATA[下面演示了用户控件调用父页面SetLaeble方法。
父页面类型用反射的方法获取，这避免了不同页面调用同样时，需要类型转换的问题（不用写很多case了:)）。

当然还有一种方法是父页面去实现一个接口，即去实现SetLabel方法，uc把this.Page转成这个接口就可以了。


用户控件:

using System.Reflection；
private void Button1_Click(object sender, System.EventArgs e)
        {
            //用反射方法动态调用父页面的方法
            System.Web.UI.Page p = this.Page；
            Type pageType = p.GetType()；
            MethodInfo mi = pageType.GetMethod("SetLabel")；
            mi.Invoke(p,new object[]{"你这个大猪猪!"})；
            
        } 

父页面： 

public void SetLabel(string str)
        {
            this.Label1.Text = str；
        } 
]]></description></item><item><link>http://h31home.com/h312005/blogview.asp?ID=990</link><title><![CDATA[用C#代码生成一个简单的PDF文件 ]]></title><author>admin</author><category>VS and C#</category><pubDate>2008-9-20 8:33:00</pubDate><guid>http://h31home.com/h312005/blogview.asp?ID=990</guid><description><![CDATA[using System；
using System.IO；
using System.Text；
using System.Collections；

namespace PDFGenerator
{
     /// <summary>
     /// Application : Generation of PDF file from text
     /// Author         : Pramod Kumar Singh 
     /// Date         : 25th July 2001
     ///</summary>
        
     public class PDFGenerator
     {
         static float pageWidth = 594.0f；
         static float pageDepth = 828.0f；
         static float pageMargin = 30.0f；
         static float fontSize = 10.0f；
         static float leadSize = 10.0f；
        
         //Create a PDF file.
         //PDF on Disk
         static StreamWriter pPDF=new StreamWriter("F:\\Temp\\myPDF.pdf")；
         //PDF in Memory
         static MemoryStream mPDF= new MemoryStream()；
        
         //Convert the Text Data to PDF format and write back to
         //Memory Stream
         static void ConvertToByteAndAddtoStream(string strMsg)
         {
             Byte[] buffer=null；
             buffer=ASCIIEncoding.ASCII.GetBytes(strMsg)；
             mPDF.Write(buffer,0,buffer.Length)；  
             buffer=null；
         }
        
         //Format the data length in xRef Format
         static string xRefFormatting(long xvalue)
         {
             string strMsg =xvalue.ToString()；
             int iLen=strMsg.Length；
             if (iLen<10)
             {
                 StringBuilder s=new StringBuilder()；
                 //string s=null；
                 int i=10-iLen；
                 s.Append('0',i)；
                 strMsg=s.ToString() + strMsg；
             }
             return strMsg；
         }

         //Entry Point
         static void Main(string[] args)
         {
             //Create a ArrayList for xRefs of PDF Document
             ArrayList xRefs=new ArrayList()；
             Byte[] buffer=null；
             float yPos =0f；
             long streamStart=0；
             long streamEnd=0；
             long streamLen =0；
             string strPDFMessage=null；
             //PDF Header Message
             strPDFMessage="%PDF-1.1\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
            
             //ID 1 For Containt
             //ID 2 For Length of the Stream
             //write the Text
            
             //1> Start a new Page
             xRefs.Add(mPDF.Length)；
             strPDFMessage="1 0 obj\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
             strPDFMessage="<< /Length 2 0 R >>\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
             strPDFMessage="stream\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
            
             //Get the start of the stream
             streamStart=mPDF.Length；
             strPDFMessage="BT\n/F0 " + fontSize +" Tf\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
             yPos = pageDepth - pageMargin；
             strPDFMessage=pageMargin + " " + yPos +" Td\n" ；
             ConvertToByteAndAddtoStream(strPDFMessage)；
             strPDFMessage= leadSize+" TL\n" ；
             ConvertToByteAndAddtoStream(strPDFMessage)；
            
             //Add the text data to the PDF memory stream
             strPDFMessage= "(Pramod Kumar Singh)Tj\n" ；
             ConvertToByteAndAddtoStream(strPDFMessage)；
             strPDFMessage= "ET\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
             //Get the End of the stream
             streamEnd=mPDF.Length；
             //Get the Length of the stream
             streamLen=streamEnd-streamStart；
             strPDFMessage= "endstream\nendobj\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
                    
             //Add 2 object to xRef
             xRefs.Add(mPDF.Length)；
             strPDFMessage="2 0 obj\n"+ streamLen + "\nendobj\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
                        
             //Add Page to xRefs
             xRefs.Add(mPDF.Length)；
             strPDFMessage="3 0 obj\n<</Type/Page/Parent 4 0 R/Contents 1 0 R>>\nendobj\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
            
             //Build the Pages
             xRefs.Add(mPDF.Length)；
             strPDFMessage="4 0 obj\n<</Type /Pages /Count 1\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
             strPDFMessage="/Kids[\n3 0 R\n]\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
             strPDFMessage="/Resources<</ProcSet[/PDF/Text]/Font<</F0 5 0 R>> >>\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
             strPDFMessage="/MediaBox [ 0 0 "+ pageWidth + " " + pageDepth + " ]\n>>\nendobj\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
            
             //Add font to xRefs
             xRefs.Add(mPDF.Length)；
             strPDFMessage="5 0 obj\n<</Type/Font/Subtype/Type1/BaseFont/Courier/Encoding/WinAnsiEncoding>>\nendobj\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
                    
             //Add the catalog to xRefs
             xRefs.Add(mPDF.Length)；
             strPDFMessage="6 0 obj\n<</Type/Catalog/Pages 4 0 R>>\nendobj\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
                        
             //xRefs Entry 
             streamStart=mPDF.Length；
             strPDFMessage="xref\n0 7\n0000000000 65535 f \n"；
             for(int i=0；i<xRefs.Count；i++)
             {
                 strPDFMessage+=xRefFormatting((long) xRefs[i])+" 00000 n \n"；
             }
             ConvertToByteAndAddtoStream(strPDFMessage)；
             //Trailer for the PDF
             strPDFMessage="trailer\n<<\n/Size "+ (xRefs.Count+1)+"\n/Root 6 0 R\n>>\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
             //xRef location entry
             strPDFMessage="startxref\n" + streamStart+"\n%%EOF\n"；
             ConvertToByteAndAddtoStream(strPDFMessage)；
             //Write the PDF from Memory Stream to File Stream
             mPDF.WriteTo(pPDF.BaseStream)；
             //Close the Stream
             mPDF.Close()；
             pPDF.Close()；
         }
     }
} ]]></description></item><item><link>http://h31home.com/h312005/blogview.asp?ID=989</link><title><![CDATA[SQL 中 Ｓelect 语句的执行顺序 ]]></title><author>admin</author><category>Oralce</category><pubDate>2008-9-20 8:31:02</pubDate><guid>http://h31home.com/h312005/blogview.asp?ID=989</guid><description><![CDATA[    好像自已在书写 SQL 语句时由于不清楚各个关键字的执行顺序, 往往组织的 SQL 语句缺少很好的逻辑, 凭感觉 "拼凑" ( 不好意思, 如果您的 SQL 语句也经常 "拼凑", 那您是不是得好好反省一下呢?, 呵呵). 确实是爽了自己, 可苦了机器, 服务器还需要在我们的杂乱无章的 SQL 语句中寻找它下一句需要执行的关键字在哪里. 效率嘛, 由于我们的感觉神经对秒以下的变化实在不敏感, 暂且就认为自已写的 SQL 顺序无关紧要, "反正没什么变化!", 呵呵.其实服务器对每句 SQL 解析时间都会有详细记录的, 大家可以看一下自已按习惯写的 SQL 和按标准顺序写的SQL解析时间差别有多大.
   因此, 建议大家在平时工作中 SQL 语句按标准顺序写, 一是专业, 二是实用, 呵呵, 不过我觉得最主要的是心里感觉舒服.
   标准的 SQL 的解析顺序为:
   (1).FROM 子句, 组装来自不同数据源的数据
   (2).WHERE 子句, 基于指定的条件对记录进行筛选
   (3).GROUP BY 子句, 将数据划分为多个分组
   (4).使用聚合函数进行计算
   (5).使用 HAVING 子句筛选分组
   (6).计算所有的表达式
   (7).使用 ORDER BY 对结果集进行排序

   举例说明: 在学生成绩表中 (暂记为 tb_Grade), 把 "考生姓名"内容不为空的记录按照 "考生姓名" 分组, 并且筛选分组结果, 选出 "总成绩" 大于 600 分的.
   标准顺序的 SQL 语句为: 
   Ｓelect 考生姓名, max(总成绩) as max总成绩
   from tb_Grade
   where 考生姓名 is not null
   group by 考生姓名
   having max(总成绩) > 600
   order by max总成绩
   
   在上面的示例中 SQL 语句的执行顺序如下:
   (1). 首先执行 FROM 子句, 从 tb_Grade 表组装数据源的数据
   (2). 执行 WHERE 子句, 筛选 tb_Grade 表中所有数据不为 NULL 的数据
   (3). 执行 GROUP BY 子句, 把 tb_Grade 表按 "学生姓名" 列进行分组
   (4). 计算 max() 聚集函数, 按 "总成绩" 求出总成绩中最大的一些数值
   (5). 执行 HAVING 子句, 筛选课程的总成绩大于 600 分的.
   (7). 执行 ORDER BY 子句, 把最后的结果按 "Max 成绩" 进行排序.
]]></description></item><item>
<link>http://h31home.com/rss/blogto.asp?ID=47295</link>
<title><![CDATA[性能优化总结。]]></title>
<author>月阳</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-9 23:51:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47295</guid>
<description><![CDATA[ <p>阅读: 129 评论: 1 作者: 月阳 发表于 2010-03-09 23:51 原文链接</p><p>&nbsp;&nbsp;&nbsp; 最近在领导的要求下做了一下项目的优化，总结如下：</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 1.&nbsp;&nbsp;&nbsp; 使用存储过程， （如果在程序里用exec 存储过程 参数，这样执行似乎并没有快多少）</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在数据库里是预编译的，也不需要在字符串传输上花费大量时间。&nbsp; 防sql注入攻击。</p>
<p>&nbsp;&nbsp;&nbsp; 2.&nbsp;&nbsp;&nbsp;&nbsp; 尽量优化数据库语句，使逻辑尽量简单。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@&nbsp; 还有就是在使用函数时&nbsp;&nbsp;&nbsp; charindex&nbsp;&nbsp; &gt;like &gt; padindex&nbsp; 效率依次递减。&nbsp;&nbsp; @查询字段是否包含在以，分隔的字段串时，最好不要用in&nbsp; 速度非常慢。&nbsp; 还有好多，可以总结的，这里就不再描述了。</p>
<p>&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp; 3.&nbsp;&nbsp;&nbsp;EnableViewState(页面的视图状态)。如果无特殊要求设置为false。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使用ViewState ，每个对象都必须先序列化到 ViewState 中，然后再通过回传进行反序列化，因此使用 ViewState是没有代价的。尽量减少使用对象，如果可能，尽量减少放入 ViewState 中的对象的数目。下面情况基本上可以禁用viewstate：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （1）页面控件 （.ascx）</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （2）页面不回传给自身。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （3）无需对控件的事件处理。 </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （4）控件没有动态的或数据绑定的属性值（或对于每个postpack都在代码中处理）</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 单个页面或每个页面都禁用 ViewState，如下所示：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 单个页面：&lt;%@ Page EnableViewState="False" %&gt; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 每个页面：在 web.config 中 &lt;Pages EnableViewState="false" /&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;EnableSessionState保持默认值即可（如果页面用到sessionstate它才会占用资源）。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;EnableViewStateMac如果无安全上的特殊要求，保持默认值。</p>
<p>&nbsp;&nbsp; 4.&nbsp;&nbsp; Pagelayout.页面布局模型。建议使用Flowlayout(元素不带绝对定位属性添加).Gridlayout(绝对定位属性)由于采用绝对定位，将会比Flowlayout生产更多的代码，主要是控件的定位信息。&nbsp; radiobuttonlist&nbsp;&nbsp; 和&nbsp; checkboxlist等</p>
<p>&nbsp;&nbsp; 5.&nbsp;&nbsp; 项目发布的时候切记解除页面的Debug状态</p>
<p>&nbsp;&nbsp; 6.&nbsp;&nbsp; 尽量选择html控件。能在客户端实现的功能就在客户端实现(熟练掌握javascript)，减少服务器的压力。数据控件选择顺序：Repeater、DataList、DataGrid</p>
<p>&nbsp;&nbsp; 7.&nbsp;&nbsp; 在建立数据库连接后只有在真正需要操作时才打开连接，使用完毕后马上关闭，从而尽量减少数据库连接打开的时间，避免出现超出连接限制的情况</p>
<p>&nbsp;&nbsp; 8.&nbsp;&nbsp; 字符串操作性能优化</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>&nbsp;使用值类型的ToString方法<br /></span>　　在连接字符串时，经常使用"+"号直接将数字添加到字符串中。这种方法虽然简单，也可以得到正确结果，但是由于涉及到不同的数据类型，数字需要通过装箱&nbsp;&nbsp;&nbsp; 操&nbsp;。作转化为引用类型才可以添加到字符串中。但是装箱操作对性能影响较大，因为在进行这类处理时，将在托管堆中分配一个新的对象，原有的值复制到新创建的对象中。使用值类型的ToString方法可以避免装箱操作，从而提高应用程序性能。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #333333;">运用StringBuilder类<br /></span>　　String类对象是不可改变的，对于String对象的重新赋值在本质上是重新创建了一个String对象并将新值赋予该对象，其方法 ToString对性能的提高并非很显著。在处理字符串时，最好使用StringBuilder类，其.NET 命名空间是System.Text。该类并非创建新的对象，而是通过Append，Remove，Insert等方法直接对字符串进行操作，通过 ToString方法返回操作结果。&nbsp;</p>
<p>&nbsp;&nbsp; 9.只要可能就缓存数据或页输出</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; ASP.NET 提供了一些简单的机制，它们会在不需要为每个页请求动态计算页输出或数据时缓存这些页输出或数据。另外，通过设计要进行缓存的页和数据请求(特别是在站点中预期将有较大通讯量的区域)，可以优化这些页的性能。与 .NET Framework 的任何 Web 窗体功能相比，适当地使用缓存可以更好的提高站点的性能，有时这种提高是超数量级的。使用 ASP.NET 缓存机制有两点需要注意。首先，不要缓存太多项。缓存每个项均有开销，特别是在内存使用方面。不要缓存容易重新计算和很少使用的项。其次，给缓存的项分配的有效期不要太短。很快到期的项会导致缓存中不必要的周转，并且经常导致更多的代码清除和垃圾回收工作。若关心此问题，请监视与 ASP.NET Applications 性能对象关联的 Cache Total Turnover Rate 性能计数器。高周转率可能说明存在问题，特别是当项在到期前被移除时。这也称作内存压力。</p>
<p>&nbsp;10. 使用 HttpServerUtility.Transfer 方法在同一应用程序的页面间重定向<br />　　采用 Server.Transfer 语法，在页面中使用该方法可避免不必要的客户端重定向。但要根据情况区分response.redirect .response.execute的使用方法。 区别对待。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp; 11.适当地使用公共语言运行库的垃圾回收器和自动内存管理<br />　　小心不要给每个请求分配过多内存，因为这样垃圾回收器将必须更频繁地进行更多的工作。另外，不要让不必要的指针指向对象，因为它们将使对象保持活动状态，并且应尽量避免含 Finalize 方法的对象，因为它们在后面会导致更多的工作。特别是在 Finalize 调用中永远不要释放资源，因为资源在被垃圾回收器回收之前可能一直消耗着内存。最后这个问题经常会对 Web 服务器环境的性能造成毁灭性的打击，因为在等待 Finalize 运行时，很容易耗尽某个特定的资源。</p>
<p>&nbsp;&nbsp; 12<strong>.</strong>不要依赖代码中的异常</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 因为异常大大地降低性能，所以您不应该将它们用作控制正常程序流程的方式。如果有可能检测到代码中可能导致异常的状态，请执行这种操作。不要在处理该状态之前捕获异常本身。常见的方案包括：检查 null，分配给将分析为数字值的 String 一个值，或在应用数学运算前检查特定值。下面的示例演示可能导致异常的代码以及测试是否存在某种状态的代码。</p>
<p>&nbsp;&nbsp; 13.使用 HttpResponse.Write 方法进行字符串串联<br />　　该方法提供非常有效的缓冲和连接服务。但是，如果您正在执行广泛的连接，请使用多个 Response.Write 调用。下面示例中显示的技术比用对 Response.Write 方法的单个调用连接字符串更快。</p>
<div class="quote">&nbsp;&nbsp;&nbsp;&nbsp; Response.Write("atest");<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write(strString);<br />&nbsp;&nbsp;&nbsp;&nbsp; Response.Write("boxbig");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 14.除非有特殊的原因要关闭缓冲，否则使其保持打开<br />　　禁用 Web 窗体页的缓冲会导致大量的性能开销。</div>
<div class="quote">&nbsp;&nbsp;&nbsp;15.避免到服务器的不必要的往返过程<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使用 Page.IsPostBack 避免对往返过程执行不必要的处理<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 虽然您很可能希望尽量多地使用 Web 窗体页框架的那些节省时间和代码的功能，但在某些情况下却不宜使用 ASP.NET 服务器控件和回发事件处理。通常，只有在检索或存储数据时，您才需要启动到服务器的往返过程。多数数据操作可在这些往返过程间的客户端上进行。</div>
<div class="quote">&nbsp;&nbsp; 16.<strong>ASP.NET应用程序性能测试</strong><br />　　在对ASP.NET应用程序进行性能测试之前，应确保应用程序没有错误，而且功能正确。具体的性能测试可以采用以下工具进行：Web Application Strees Tool (WAS)是Microsoft发布的一个免费测试工具，可以从http://webtool.rte.microsoft.com/上下载。它可以模拟成百上千个用户同时对web应用程序进行访问请求，在服务器上形成流量负载，从而达到测试的目的，可以生成平均TTFB、平均TTLB等性能汇总报告。 Application Center Test (ACT) 是一个测试工具，附带于Visual Studio.NET的企业版中，是Microsoft正式支持的web应用程序测试工具。它能够直观地生成图表结果，功能比WAS多，但不具备多个客户机同时测试的能力。服务器操作系统"管理工具"中的"性能"计数器，可以对服务器进行监测以了解应用程序性能。</div>
<div class="quote">&nbsp;&nbsp; 17.&nbsp; 压缩js，js在页面中调用的大小写要保持一致，免得缓存了不同的文件，页面的js可以的话，写成单位的文件进行调用 。图片少用jpeg，使用gzip 对网页进行压缩. 加快页面展示速度。</div>
<div class="quote">&nbsp;&nbsp; 18.&nbsp;&nbsp;把调用js，尽量写在页面底部， 还有viewstate 状态也可以重写到页面低部， 也可以把viewstate进行压缩。条件是viewstate必要要用的情况之下。</div>
<div class="quote"></div>
<div class="quote"></div>
<div class="quote">里面好多都是从网上搜集的。 </div><img src="http://www.cnblogs.com/sunrise/aggbug/1682108.html?type=1" width="1" height="1" alt=""/><p>评论: 1　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· Windows版Opera存高危缺陷 正开发补丁软件<span style="color:gray">(2010-03-09 23:01)</span><br/>· 亚马逊招募浏览器开发者 Kindle将配专用浏览器<span style="color:gray">(2010-03-09 22:37)</span><br/>· 斯坦福大学调查：学生用户对iPhone迷恋成瘾<span style="color:gray">(2010-03-09 22:32)</span><br/>· 浏览器大穿越，体验恐龙级浏览器Mosaic<span style="color:gray">(2010-03-09 22:26)</span><br/>· 美国网民平均每人月观看近200段视频<span style="color:gray">(2010-03-09 22:20)</span><br/></p><p>编辑推荐：微软 MIX10在即，我们会看到什么？<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47293</link>
<title><![CDATA[德国艺术家Dornroeschen Filzunikate的手工艺术猫窝]]></title>
<author>youhuang</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-9 14:32:46</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47293</guid>
<description><![CDATA[ <p><img border=0 src="http://img.diglog.com/img/2010/3/middle_1e379dc3a1f740bdaf7064c80ed14d76.jpg" /></p><br/>德国艺术家Dornroeschen Filzunikate用羊毛毡做的漂亮温暖的猫窝。羊毛毡保暖还不容易脏，清洗也容易。网上有卖羊毛毡的，有兴趣的猫友可以试着为自己的猫咪做一个艺术猫窝。<br/><br/>原始链接:http://www.unicornblog.cn/user1/unicornblog/index.html<br/>diglog链接:http://www.diglog.com/story/life_pet_332062.html  ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47289</link>
<title><![CDATA[ASP.NET Sql Server安装向导（aspnet_regsql.exe）错误解决一例]]></title>
<author>lerit</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-9 13:22:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47289</guid>
<description><![CDATA[ <p>阅读: 210 评论: 3 作者: lerit 发表于 2010-03-09 13:22 原文链接</p><p>这个程序是注册网站的数据库，从而提供Membership , Role , Profile 等等诸多功能和管理权限的控件的使用。今天也自己试试用这个工具来配置一下。首先在数据库中建立了一个数据库，名称为TESTDB，然后新建了一个sqlserver的登录名（testdb），指定了testdb为TESTDB的默认数据库。然后就开始配置了。</p> <p>配置过程是参考《aspnet_regsql.exe 工具注册数据库》的，但是到了选择服务器和数据库时候，填写了正确的服务器名，选择sql server身份验证，填写了新建的testdb用户名和密码，然后点选下拉框来选择目标数据库，此时出现了错误提示：（<font color="#ff0000">未能查询SQL Server中的数据库名称列表。无法打开用户默认数据库，登录失败，用户‘testdb’登录失败</font>）</p> <p><img title="1" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="407" alt="1" src="http://images.cnblogs.com/cnblogs_com/lerit/WindowsLiveWriter/ASP.NETSqlServeraspnet_regsql.exe_BBF3/1_thumb.jpg" width="705" border="0"> </p> <p>哦哦，对了，忘了授权了，这个用户没有登录权限呢，为了保证不会因为是权限问题而导致配置失败，我给予此用户sysadmin的最高权限。然后重新运行于此，但是依然报如下错误：（<font color="#ff0000">未能查询SQL Server中的数据库名称列表。对象名‘sysdatabases’无效</font>）</p> <p><img title="2" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="404" alt="2" src="http://images.cnblogs.com/cnblogs_com/lerit/WindowsLiveWriter/ASP.NETSqlServeraspnet_regsql.exe_BBF3/2_thumb.jpg" width="704" border="0"> </p> <p>这就奇怪了，我试了试用sa，就没问题，可以显示数据库中的所有数据库的名称，莫非还是权限不够？？我知道sysdatabases是系统表中的一个视图，用于读取所有的数据库名，于是用testdb登录数据库，试着执行此命令：</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select * from sys.sysdatabases</p> <p>没问题，可以显示出各个表名啊，应该不是这个访问权限问题。那怎么办?</p> <p><strong>解决办法：</strong>抱着试试的态度，我在上面图中的数据库那个下拉框中，直接填写了我的数据库名：TESTDB，点击下一步，竟然通过了~~~，配置成功后，去数据库中查看，果然有自动生成的那11个以asp_开头的表和那些试图和存储过程等。</p> <p>结论：不知道问题出在哪里，虽然没有解决这个“问题”，但是绕过去了，所以，应该是配置工具的问题。</p><img src="http://www.cnblogs.com/lerit/aggbug/1681580.html?type=1" width="1" height="1" alt=""/><p>评论: 3　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· 一家行业组织将推进开源数据中心设计<span style="color:gray">(2010-03-09 14:33)</span><br/>· Goole与Dish Network合作 测试新电视节目搜索服务<span style="color:gray">(2010-03-09 14:17)</span><br/>· 人人网推出网络招聘平台<span style="color:gray">(2010-03-09 14:07)</span><br/>· iPhone专用香肠上市 韩国人表示这是模仿<span style="color:gray">(2010-03-09 13:58)</span><br/>· 盛大可以模仿迪斯尼，但模仿不出米老鼠<span style="color:gray">(2010-03-09 13:48)</span><br/></p><p>编辑推荐：关于 HTML5，开发者可以期待什么？<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47290</link>
<title><![CDATA[WF4.0：从XAML中加载工作流]]></title>
<author>麒麟</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-9 12:53:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47290</guid>
<description><![CDATA[ <p>阅读: 260 评论: 7 作者: 麒麟 发表于 2010-03-09 12:53 原文链接</p><p>
<p><span style="color: red"></span></p>&nbsp;&nbsp;&nbsp; 大多数时候，我在Windows Workflow Foundation 4编译工作流时，它非常简单和方便，先设计工作流，然后编译和在运行时就会有一个用于创建和运行工作流的.NET类型。主要缺点是，这种方法不是很灵活，有时你希望能够在运行时改变您的工作流的定义或者将它存储在数据库中，重新编译是不可取的。 
<p>&nbsp;&nbsp;&nbsp; 幸运的是，我们还可以从XAML文件本身加载工作流和执行返回的工作流活动。使用ActivityXamlServices类能做到这些，它将让我们加载XAML文件并返回一个活动，确切地说，它返回一个封装好流程定义的DynamicActivity。</p>
<p>&nbsp;&nbsp;&nbsp; 最简单的方法就是传递一个文件名做参数调用Load() ，例如：&nbsp;</p>
<div class="cnblogs_code">
<div><!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--><span style="color: #000000">Activity&nbsp;workflow&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;ActivityXamlServices.Load(</span><span style="color: #800000">"</span><span style="color: #800000">YourWorkflow.xaml</span><span style="color: #800000">"</span><span style="color: #000000">);</span></div></div>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 如果您使用本地程序集中的活动或其他类型，这是要失败的，但你可以用稍微详细方式去实现，例如：</p>
<div class="cnblogs_code">
<div><!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--><span style="color: #000000">var&nbsp;settings&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;XamlXmlReaderSettings()&nbsp;{&nbsp;LocalAssembly&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;typeo(SendForManualApproval).Assembly&nbsp;};<br />var&nbsp;reader&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;XamlXmlReader(</span><span style="color: #800000">"</span><span style="color: #800000">YourWorkflow.xaml</span><span style="color: #800000">"</span><span style="color: #000000">,&nbsp;settings);<br />Activity&nbsp;workflow&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;ActivityXamlServices.Load(reader);</span></div></div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;需要使用XamlXmlReaderSettings来说明XAML需要引用那些本地的程序集。</p>
<p><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp; 备注：这篇文章的使用环境是</span><font color="#ff0000"><span style="color: #000000">.NET framework 4.0 RC 1</span></font></p>
<p><span style="color: #000000">&nbsp;&nbsp;&nbsp; 原文：</span>http://msmvps.com/blogs/theproblemsolver/archive/2010/03/07/loading-xaml-workflows-in-wf4.aspx</p> <img src="http://www.cnblogs.com/zhuqil/aggbug/1681547.html?type=1" width="1" height="1" alt=""/><p>评论: 7　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· 一家行业组织将推进开源数据中心设计<span style="color:gray">(2010-03-09 14:33)</span><br/>· Goole与Dish Network合作 测试新电视节目搜索服务<span style="color:gray">(2010-03-09 14:17)</span><br/>· 人人网推出网络招聘平台<span style="color:gray">(2010-03-09 14:07)</span><br/>· iPhone专用香肠上市 韩国人表示这是模仿<span style="color:gray">(2010-03-09 13:58)</span><br/>· 盛大可以模仿迪斯尼，但模仿不出米老鼠<span style="color:gray">(2010-03-09 13:48)</span><br/></p><p>编辑推荐：关于 HTML5，开发者可以期待什么？<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47291</link>
<title><![CDATA[WF4.0 RC 官方示例]]></title>
<author>魔幻天空</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-9 11:57:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47291</guid>
<description><![CDATA[ <p>阅读: 528 评论: 2 作者: 魔幻天空 发表于 2010-03-09 11:57 原文链接</p><p>伴着RC的发布,微软给出了WF4.0 RC的Samples,为大家学习提供了很好的资源.不过我的机器有一些项目打开之后会报错,不能显示XAML的流程图,不知是不是个别现象.</p>
<p>下载地址为:</p>
<p>http://download.microsoft.com/download/1/5/9/159D6D71-7728-45D4-BC15-5DF1F2DDCD94/WF_WCF_Samples.exe&nbsp;</p>
<p>内容分类如下:</p>
<p>Application (Samples)--整体演示</p>
<blockquote>
<p><span style="color: #000000;">-Document Approval Process (文档审批,一个基本的业务流程)</span></p>
<p><span style="color: #000000;">-Corporate Purchase Process(企业采购,服务寄宿于web&amp;win)</span></p>
<p><span style="color: #000000;">-Hiring Process(雇佣流程,使用Messaging Activities,多流程同时存在于WorkflowServiceHost)</span></p>
<p><span style="color: #000000;">-Visual Workflow Tracking(可视化流程跟踪.利用流程设计器WorkflowDesigner实现可视化跟踪)</span></p>
<p><span style="color: #000000;">-Suspended Instance Management(演示流程挂起)</span></p>
</blockquote>
<p>Basic--细节讲解</p>
<blockquote>
<p><span style="color: #000000;">-Built-in Activities(Activity使用)</span></p>
<p><span style="color: #000000;">-Compensation (Samples)(使用补偿及自定义补偿)</span></p>
<p><span style="color: #000000;">-Custom Activities(自定义Activity)</span></p>
<p><span style="color: #000000;">-Designer(设计器编程-这里主要讲使用对自带设计器编程)</span></p>
<p><span style="color: #000000;">-Designer ReHosting(设计器重寄宿,自定义流程设计器)</span></p>
<p><span style="color: #000000;">-Execution(执行工作流,包括三种方式&lt;WorkflowApplication&gt;&lt;WorkflowInvoker&gt;&lt;WorkflowServiceHost&gt;)</span></p>
<p><span style="color: #000000;">-Expressions(使用VB表达式)[这个例子我用RC打开竟然报错!,看了下XAML例子很简单,输入一些参数,利用VB表达式求个最大最小值,再输出,不看也罢]</span></p>
<p><span style="color: #000000;">-Migration(迁移,包括将3.0,3.5的工作流迁移至4.0上来,以及将旧版本的Activity包装,以便4.0调用的</span></p>
<p>Interop activity演示) </p>
<p>-Persistence(持久化,讲解利用默认的持久化数据库进行跟踪以及自定义持久化服务) </p>
<p>-Rules Samples(规则) </p>
<p>-Services(WF其他服务)[这部分内容比较杂,主要四对一些个人认为不太常用的服务进行演示) </p>
<p>-Tracking(跟踪服务,讲解利用默认的Tracking数据库进行跟踪以及自定义Tracking服务) </p>
<p>-Transactions(使用事务) </p>
<p>-Validation(验证,提供对WF流程中参数添加约束的实现方法)</p>
</blockquote>
<p>Scenario--应用方案</p>
<blockquote>
<p><span style="color: #000000;">-Activity Library(Activity应用方案,同时提供了一些自定义的Activity)</span></p>
<p><span style="color: #000000;">-Services(服务应用发难)</span></p>
<p><span style="color: #000000;">-Transactions(事务应用方案)</span></p>
<p><span style="color: #000000;">-Auto-Confirm Pattern(自动完成模式,实现了一个自动完成Scope,包括[第一次同意后,再次进入将自动同意]等功能)</span></p>
<p><span style="color: #000000;">-StateMachine Scenario Using a Combination of FlowChart and Pick(用FlowChart和Pick两个Activity实现秒表)</span></p>
<p><span style="color: #000000;">-WPF and WF Integration in XAML(WF和WPF整合,例子给出的是将WPF的窗体XAML应用到到WF中,同时利用窗体对WF参数进行赋值)</span></p>
<p><span style="color: #000000;">-External Ruleset Toolkit(提供一个有关如何具体化工作流程序集的规则的示例)</span></p>
</blockquote><img src="http://www.cnblogs.com/Magicsky/aggbug/1681490.html?type=1" width="1" height="1" alt=""/><p>评论: 2　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· 一家行业组织将推进开源数据中心设计<span style="color:gray">(2010-03-09 14:33)</span><br/>· Goole与Dish Network合作 测试新电视节目搜索服务<span style="color:gray">(2010-03-09 14:17)</span><br/>· 人人网推出网络招聘平台<span style="color:gray">(2010-03-09 14:07)</span><br/>· iPhone专用香肠上市 韩国人表示这是模仿<span style="color:gray">(2010-03-09 13:58)</span><br/>· 盛大可以模仿迪斯尼，但模仿不出米老鼠<span style="color:gray">(2010-03-09 13:48)</span><br/></p><p>编辑推荐：关于 HTML5，开发者可以期待什么？<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47292</link>
<title><![CDATA[小论面向对象编程方法]]></title>
<author>袁永福</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-9 11:21:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47292</guid>
<description><![CDATA[ <p>阅读: 612 评论: 1 作者: 袁永福 发表于 2010-03-09 11:21 原文链接</p><div style="layout-grid:  15.6pt none">
<p><span style="font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;在软件开发中，使用面向对象编程方法是一种放长线吊大鱼的策略，首先要高瞻远瞩，然后精耕细作，最后全面开花完成软件开发任务。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">面向对象编程思想是适应当前软件开发规模原来越大，复杂度越来越高的情况。软件开发的工作量随着软件规模的增加而呈非线性增长，软件规模越大，软件开发工作量增长的速度越来快。而使用传统的面向过程的编程方法，开发人员的工作量和软件开发工作量是成正比的，因此当软件规模很大时，开发人员的工作量将非常巨大，从而导致软件开发成本急剧上升，这对于商业软件开发是不可行的。而软件客户的复杂的需求是客观存在的，是需要满足的，因此业界开始使用面向对象的编程方法来降低软件开发成本。【袁永福 http://www.cnblogs.com/xdesigner】</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">从宏观上看，面向对象编程思想的最大的作用就是将一个整体上复杂的软件功能拆分成多个功能简单的软件功能，然后以较低的成本实现各个简单的软件功能，最后进行模块集成形成一个完整而复杂的软件功能来满足用户需求。采用的是分割包围，各个击破的策略。</span></p>
<p style="text-indent: 21pt"></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/oop-split.gif" width="415" height="279" /></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">如上图所示，阴影部分的面积就是软件开发工作量。当采用面向过程的软件开发方法，当客户需求很复杂时，软件开发工作量将非常大，而采用面向对象的软件开发方法时，开发人员可以将复杂的客户需求拆分成两个较为简单的客户需求，然后逐一开发，最后进行集成实现所需的功能，此时软件开发工作量降低了一半，是否采用正确的方法，效果的对比是惊人的。因此采用面向对象的软件开发方法，以较低的成本开发客户需求复杂的商业软件成为现实。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">从软件开发过程看，面向对象编程思想强制添加了一个软件抽象的步骤，迫使软件开发人员需要跟深入的了解和分析用户需求，从而增加了软件开发流程的稳定性和正规性。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">从实现方法上看，面向对象编程思想更加符合人们对客观事物的理解方法。考察人们在理解客户事物的过程，人们会有意无意的将诸多事物进行分类整理和对比。【袁永福 http://www.cnblogs.com/xdesigner】</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">比如人们经过大量的认识，把汽车抽象理解为有至少</span>4<span style="font-family: 宋体">个轮子和</span>2<span style="font-family: 宋体">个车轴的机动车辆，而客车就是专门运输人员的汽车，公交车就是任何人交费就可以乘坐的客车。于是形成了&#8220;机动车</span>&#8212;<span style="font-family: 宋体">汽车</span>&#8212;<span style="font-family: 宋体">客车</span>&#8212;<span style="font-family: 宋体">公交车&#8221;这</span>4<span style="font-family: 宋体">种客观事物和</span>3<span style="font-family: 宋体">个派生关系构成的关于汽车的认识。这个认识方式学习成本低，速度快，知识能重复利用是其最大的优点。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">若不用这种分类比较的方法，则汽车就定义为至少</span>4<span style="font-family: 宋体">个轮子</span>2<span style="font-family: 宋体">个车轴的机动车；客车就是专门运输人员的至少</span>4<span style="font-family: 宋体">个轮子和</span>2<span style="font-family: 宋体">个车轴的机动车；公交车就是任何人交费就可以乘坐的专门用于运输人员的至少有</span>4<span style="font-family: 宋体">个轮子和</span>2<span style="font-family: 宋体">个车轴的机动车。对于两种认知方式可以进行如下对比【袁永福 http://www.cnblogs.com/xdesigner】</span></p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 41.4pt; padding-right: 5.4pt;background: #f3f3f3; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="55">
<p><span style="font-family: 宋体">事物</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 189pt; padding-right: 5.4pt;background: #f3f3f3; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="252">
<p><span style="font-family: 宋体">分类对比</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 195.7pt; padding-right: 5.4pt;background: #f3f3f3; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="261">
<p><span style="font-family: 宋体">不分类对比</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 41.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="55">
<p><span style="font-family: 宋体">汽车</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 189pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="252">
<p><span style="font-family: 宋体">至少有</span>4<span style="font-family: 宋体">个轮子和</span>2<span style="font-family: 宋体">个车轴的机动车。</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 195.7pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="261">
<p><span style="font-family: 宋体">至少有</span>4<span style="font-family: 宋体">个轮子和</span>2<span style="font-family: 宋体">个车轴的机动车。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 41.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="55">
<p><span style="font-family: 宋体">客车</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 189pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="252">
<p><span style="font-family: 宋体">专门运输人员的汽车。</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 195.7pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="261">
<p><span style="font-family: 宋体">专门运输人员的至少</span>4<span style="font-family: 宋体">个轮子和</span>2<span style="font-family: 宋体">个车轴的机动车。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 41.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="55">
<p><span style="font-family: 宋体">公交车</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 189pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="252">
<p><span style="font-family: 宋体">任何人交费就可以乘坐的客车。</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 195.7pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="261">
<p><span style="font-family: 宋体">任何人交费就可以乘坐的专门用于运输人员的至少有</span>4<span style="font-family: 宋体">个轮子和</span>2<span style="font-family: 宋体">个车轴的机动车。</span></p></td></tr></tbody></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">显而易见，若不采用分类对比的认知方式，人们认知事物的成本就大为增加，相信任何人都没能力能认识这个世界的繁杂事物的。但事实上，智力正常的人都自觉地采用这种分类对比的认知方法，从而轻易的认知周围所有的事物。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">软件开发也一样，软件是开发人员对客户需求的认知的表述。不理解功能需求就不可能开发出正确的软件。就像汽车一样，用户需求也是客观存在的事物，面对复杂的客户需求，采用分类对比的方式是明智之举。因此面向对象的编程方法就是分类对比的方法在软件开发中的具体实现。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">分类对比的认知方式最大的优势就是知识的重复利用，于是面向对象编程思想最大的优势就是代码的重复利用。代码的重复利用有两大好处，一个就是代码寿命明显变长，能很大的保护客户的投资，另外一个就是能层层积累，降低对新知识的学习量。【袁永福 http://www.cnblogs.com/xdesigner】</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">代码就是客户已有的投资的结果，商业软件开发人员应当要充分的考虑到对客户已有投资的保护，在成本允许的情况下旧代码应当尽量保存。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">代码是软件的细胞，代码的长寿是软件长寿的基础，也是客户的投资价值最大化的基础。</span></p>
<p>&nbsp;</p></div><img src="http://www.cnblogs.com/xdesigner/aggbug/1681449.html?type=1" width="1" height="1" alt=""/><p>评论: 1　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· 一家行业组织将推进开源数据中心设计<span style="color:gray">(2010-03-09 14:33)</span><br/>· Goole与Dish Network合作 测试新电视节目搜索服务<span style="color:gray">(2010-03-09 14:17)</span><br/>· 人人网推出网络招聘平台<span style="color:gray">(2010-03-09 14:07)</span><br/>· iPhone专用香肠上市 韩国人表示这是模仿<span style="color:gray">(2010-03-09 13:58)</span><br/>· 盛大可以模仿迪斯尼，但模仿不出米老鼠<span style="color:gray">(2010-03-09 13:48)</span><br/></p><p>编辑推荐：关于 HTML5，开发者可以期待什么？<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47294</link>
<title><![CDATA[LED羽毛球套装---创意产品----酷品网]]></title>
<author>koodj</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-9 11:15:01</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47294</guid>
<description><![CDATA[ <p><img border=0 src="http://img.diglog.com/img/2010/3/middle_4845c94ec77c4b598c2de0946dfd6d3f.jpg" /></p><br/>给羽毛球拍和羽毛球装上LED小灯，让您可以在傍晚光线不好的时候可以多享受一会儿羽毛球运动的乐趣，相信爱好打羽毛球的您一定不会错过它。售价：39.99美元<br/><br/>原始链接:http://www.kooideas.com/Article/2254.html<br/>diglog链接:http://www.diglog.com/story/technology_design_332045.html  ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47276</link>
<title><![CDATA[因HTTP的Header长度过长导致下载文件名出现乱码的问题]]></title>
<author>酸甜西瓜</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-9 9:24:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47276</guid>
<description><![CDATA[ <p>阅读: 342 评论: 1 作者: 酸甜西瓜 发表于 2010-03-09 09:24 原文链接</p><p>&nbsp;</p>
<p><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp; 在通过IE直接下载文件的时候，我们可能会遇到一个比较常见的问题，那就是：我们下载的文件的文件名如果过长的话，就会出现，弹出的提示框的文件标题名变成乱码，即&#8220;%f%e%1&#8221;这样的乱码，而且点击保存到本地，文件的名称同样是乱码，一般我们使用的代码如下：</span></p>
<p><span style="font-size: 12pt"></span>&nbsp;</p>
<p><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp; Response.ContentType = "application/octet-stream";</span><br /><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp; Response.AddHeader("Content-disposition", "attachment;filename=" + HttpUtility.UrlEncode(strAccFileName, Encoding.UTF8) + "");</span><br /><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp; Response.CacheControl = "Private";</span><br /><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp; Response.BinaryWrite(objFileBuf);</span><br /><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp; Response.Flush();</span></p>
<p><span style="font-size: 12pt"></span>&nbsp;</p>
<p><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp; 经过我们测试，strAccFileName支持的字符长度在32个以下，如果超过该长度，即会出现我们开始描述的乱码问题，所以，我们对超过32个字符以外的字符进行了认为截取，并使用&#8220;&#8230;&#8230;&#8221;作为省略的象征，这样能够稍微缓解一下问题，毕竟不会出现客户认为的异常的乱码了，但是如果客户坚持要保证完整用户名下载，并且其用户名实在是非常的长的情况的话，那我们暂时只能考虑使用其他的下载方式，或者自己重新设计编写一个下载界面，是可以解决问题的。</span></p>
<p><span style="font-size: 12pt"></span>&nbsp;</p>
<p><span style="font-size: 12pt">&nbsp;&nbsp;&nbsp; 最后说一点，我使用的浏览器是IE8 Beta版，但启用的是IE7的应用，出现的情况却是名称的前面字符出现了乱码，但是，有一部分内容是正常的，但是，在IE6中，却是全部都是乱码，不知道是否做了优化？但我们最终还是选择了多截</span><span style="font-size: 12pt">取一部分内容，以保证出</span><span style="font-size: 12pt">现乱码的问题。 </span></p>
<p>&nbsp;</p><img src="http://www.cnblogs.com/guilin_gavin/aggbug/1681278.html?type=1" width="1" height="1" alt=""/><p>评论: 1　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· Mochi Media与盛大游戏成立游戏开发者基金<span style="color:gray">(2010-03-09 10:06)</span><br/>· 淘宝启动24小时自助维权平台<span style="color:gray">(2010-03-09 10:04)</span><br/>· 诺基亚两款概念手机Stealth/Dragonfly曝光<span style="color:gray">(2010-03-09 09:45)</span><br/>· IE6必须死 却没人做得到<span style="color:gray">(2010-03-09 09:41)</span><br/>· 南方日报：QQ的平台化价值是如何创造的？<span style="color:gray">(2010-03-09 09:29)</span><br/></p><p>编辑推荐：史上最强女游戏程序员<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47277</link>
<title><![CDATA[图片Silhouette Fadeins渐显效果【译自css-tricks】]]></title>
<author>Rainweb</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-9 8:55:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47277</guid>
<description><![CDATA[ <p>阅读: 315 评论: 0 作者: Rainweb 发表于 2010-03-09 08:55 原文链接</p>经常漂流在<font color="#2a7a98">css-tricks</font>看到这篇文章，就顺便搬了过来，下面译文都是用<font color="#2a7a98">css-tricks</font>口吻来描述的。 
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我的乐队有几个朋友刚刚经历了一场小型的成员阵容的变化。他们需要更换其主页上的照片。我想这可能是有趣的事情出现了少许的互动。</p>
<p><img alt="" src="http://www.rainweb.cn/download.asp?id=65" /></p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 这可能有不少方法可以做到这个效果，这一个刚刚进入我的头突然出现，我随它而去了。这个想法是有一个作为背景图像的轮廓，然后，在该组所有完全相同的大小与每个乐队成员的4个图像。这些图像默认隐藏。然后，有4个绝对定位的区域上面所在的区域，这是过渡区作用。在jQuery的，我们用他们悬停事件，渐渐显示相应的图像。</p>
<p><img alt="" src="http://www.rainweb.cn/download.asp?id=66" /></p>
<h3>&nbsp;</h3>
<h3>HTML</h3>
<p>正如我所说，只是一个div里面有四个图像和过渡区域。所有具有独特的ID和共同的class类名。</p>
<p>&lt;div id="home-photos-box"&gt;<br /><br />&nbsp;&nbsp;&nbsp; &lt;a id="aller" href="#aller" class="home-roll-box"&gt;&lt;/a&gt;<br />&nbsp;&nbsp;&nbsp; &lt;a id="neil" href="#neil" class="home-roll-box"&gt;&lt;/a&gt;<br />&nbsp;&nbsp;&nbsp; &lt;a id="aaron" href="#aaron" class="home-roll-box"&gt;&lt;/a&gt;<br />&nbsp;&nbsp;&nbsp; &lt;a id="scott" href="#scott" class="home-roll-box"&gt;&lt;/a&gt;<br /><br />&nbsp;&nbsp;&nbsp; &lt;img src="images/guys-aller.jpg" alt="" id="image-aller" class="single-guy" /&gt;<br />&nbsp;&nbsp;&nbsp; &lt;img src="images/guys-neil.jpg" alt="" id="image-neil" class="single-guy" /&gt;<br />&nbsp;&nbsp;&nbsp; &lt;img src="images/guys-aaron.jpg" alt="" id="image-aaron" class="single-guy" /&gt;<br />&nbsp;&nbsp;&nbsp; &lt;img src="images/guys-scott.jpg" alt="" id="image-scott" class="single-guy" /&gt;<br /><br />&lt;/div&gt;</p>
<p>&nbsp;</p>
<h3>CSS</h3>
<p>由类名涵盖共性（如位置样式），其次是ID的（包括具体左侧位置特殊的东西）。</p>
<p>#home-photos-box { float: left; width: 352px; background: url(../images/guys-allblack.png) no-repeat; padding: 334px 0 0 0; position: relative; }<br />#aller { left: 0; }<br />#neil { left: 25%; }<br />#aaron { left: 50%; }<br />#scott { left: 75%; }<br />.home-roll-box { position: absolute; z-index: 1000; display: block;&nbsp; height: 334px; top: 0; width: 25%; }<br />.single-guy { position: absolute; top: 0; left: 0; display: none; opacity: 0; }</p>
<p>&nbsp;</p>
<h3>jQuery</h3>
<p>当鼠标悬停到对应区域，它对应于图像的ID和褪色，这时要使用stop() ，以防止在这里排队的动画和我们使用不透明设置。fadeToggle()，当太快和滑鼠移到消退。</p>
<p>$(function() {<br />&nbsp;&nbsp;&nbsp; var name = "";<br />&nbsp;&nbsp;&nbsp; $(".home-roll-box").hover(function() {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name = $(this).attr("id");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $("#image-"+name).stop().show().animate({ opacity: 1 });<br />&nbsp;&nbsp;&nbsp; }, function() {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name = $(this).attr("id");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $("#image-"+name).stop().animate({ opacity: 0 });<br />&nbsp;&nbsp;&nbsp; });<br />});</p>
<p>&nbsp;</p>
<p>&nbsp;<font color="#2a7a98">查看demo</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#2a7a98">下载例子</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#2a7a98">原文地址</font></p><img src="http://www.cnblogs.com/rainweb/aggbug/1681244.html?type=1" width="1" height="1" alt=""/><p>评论: 0　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· Mochi Media与盛大游戏成立游戏开发者基金<span style="color:gray">(2010-03-09 10:06)</span><br/>· 淘宝启动24小时自助维权平台<span style="color:gray">(2010-03-09 10:04)</span><br/>· 诺基亚两款概念手机Stealth/Dragonfly曝光<span style="color:gray">(2010-03-09 09:45)</span><br/>· IE6必须死 却没人做得到<span style="color:gray">(2010-03-09 09:41)</span><br/>· 南方日报：QQ的平台化价值是如何创造的？<span style="color:gray">(2010-03-09 09:29)</span><br/></p><p>编辑推荐：史上最强女游戏程序员<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47278</link>
<title><![CDATA[年前的面试经历（七）]]></title>
<author>小城故事</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-9 8:45:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47278</guid>
<description><![CDATA[ <p>阅读: 971 评论: 13 作者: 小城故事 发表于 2010-03-09 08:45 原文链接</p><p>　　第二天，周四，再赴紫竹参加最后一个面试。这次乘地铁去，要换三次车，好像快不了多少。这里中软是独立的一个院子，不是租的写字楼。就在微软那座楼西南不远处，路对面就是Intel，也很好找。能在MS和Intel中间搞一个门面，应该不会太差吧。</p>
<p>　　这几次面试差不多都是提前半小时到的，这次也不例外，这里准时地让我等到三点，面试通知我要找的人－Steven终于来了，来把我带过去面试。上来照例还是一套题，我一看心中一凉，怎么是考视频播放控制呀？仔细看了半天，才明白原来那是反面的，题在另一面，英文的，不过就三道。不错，这种节约很有本人的风格！第一道要写个什么排序，先不管；第二道是编程题，关于委托事件的，看上去占了大半页纸，实际只要填四个空儿就行；第三道是英译中，关于StringBuilder类的介绍。后两道还没写完，面试我的小哥就过来问，我问他Sort前那个单词什么意思，他回答说&#8220;就写冒泡排序吧。&#8221;又冒泡！你们面试的不嫌烦，我都嫌烦。得了，三两下写完冒泡，再送您个速冻排骨(Quick Sort)吧。</p>
<p>　　我刚写完，Steven又回来了，比切广告还快。先略看了一下第二题，四个空好像错了一个。马马虎虎，正像你的风格，当年玩《太阁立志传IV》里配药方时，老得到这样评价。然后又他让我背段英文自我介绍，然后提问题。还是Web开发的老三篇，.Net/Javascript/CSS，微软面试都经过了，这些比较轻松过关。哦，对了，这个职位据说是Msn网站开发，还是蛮对口的。</p>
<p>　　又被问了些Xml的知识，还好最近研究得多一点。感觉气氛比较轻松，这个Steven也是面带微笑，慢慢聊起来参与的项目。又问了些做的项目，问倾向于做哪种开发，我说比较熟悉B/S开发，B/S又比较喜欢做前台（相对OA/ERP等管理平台)，因为能发挥出自己前端技术的长处。做管理平台，多数人都不太重视界面和用户体验。</p>
<p>　　然后，他离开了。过一会儿，第二个面试我的进来，同样问我些技术问题，.Net方面多些。后来，问我有没有参与开发的能访问的页面地址，我就随便写了几个。</p>
<p>　　他出去后不久，部门经理过来了。聊了聊个人，目标，工作情况，为什么要换工作。我问了下他这边开发方式，他说是敏捷开发，听他介绍，应该不是很山寨那种。看这位manager比较实在，就问了下他对自己有什么建议或看法，他说的也比较靠谱。</p>
<p>　　这时5点半了，天已经开始黑了，Manager说今天到这里吧，然后送我坐电梯下去。</p>
<p>　　这一定是最后一个面试了，才面了五家，现在觉得好困。看CSDN论坛，有人能7天面13个，那才叫面霸呢！最近睡觉太缺了，但面完这一圈，还是忙得补不了。要是像科比就好了，一天睡四个钟头，球照样打得虎虎生威，还不落下造人儿。全方位给你差距感，这才是偶像！</p>
<p><strong>　　（尾声）</strong></p>
<p>　　相信很多朋友关心我面试的结果，本来我也无意卖罐子。小作一个数据统计：一个多月来，投约40份简历，10个面试通知，参加5个正式面试，收到两个offer。最后两天的运气似乎好转了点。这个系列面试过程就到这里了，下篇打算总结一下。非常感谢各位朋友的支持，以及园子。祝大家2010年，工作顺利有房住，精神物质一起富！</p>
<p>&nbsp;</p>
<p>　　好像文章还短了点，再分享两段精练代码吧，以后去微软面试大家或许用得上。这是英文段落翻转：</p>
<div class="cnblogs_code">
<div><!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--><span style="color: #000000">&nbsp;var&nbsp;s&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">Best&nbsp;wishes&nbsp;to&nbsp;everyone!</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;s&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;String.Concat(Regex.Matches(s,&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">\\w+|\\W+</span><span style="color: #800000">"</span><span style="color: #000000">).Cast</span><span style="color: #000000">&lt;</span><span style="color: #000000">Match</span><span style="color: #000000">&gt;</span><span style="color: #000000">().Reverse().Select(m</span><span style="color: #000000">=&gt;</span><span style="color: #000000">m.Value).ToArray())&nbsp;;</span></div></div>
<p>&nbsp;</p>
<p>　　飞波拿鸡(要定义IEnumerable&lt;T&gt;的ForEach扩展方法)：</p>
<div class="cnblogs_code">
<div><!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--><span style="color: #000000">&nbsp;var&nbsp;N&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800080">20</span><span style="color: #000000">;<br />&nbsp;var&nbsp;list&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;Enumerable.Range(</span><span style="color: #800080">0</span><span style="color: #000000">,&nbsp;N).ToArray();<br />&nbsp;N&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;list.ForEach(n&nbsp;</span><span style="color: #000000">=&gt;</span><span style="color: #000000">&nbsp;list[n]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;n&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #800080">2</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">?</span><span style="color: #000000">&nbsp;n&nbsp;:&nbsp;list[n&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;</span><span style="color: #800080">1</span><span style="color: #000000">]&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;list[n&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;</span><span style="color: #800080">2</span><span style="color: #000000">]).Last();</span></div></div>
<p>&nbsp;</p>
<p>　　技术无止境啊！</p><img src="http://www.cnblogs.com/XmNotes/aggbug/1680697.html?type=1" width="1" height="1" alt=""/><p>评论: 13　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· Mochi Media与盛大游戏成立游戏开发者基金<span style="color:gray">(2010-03-09 10:06)</span><br/>· 淘宝启动24小时自助维权平台<span style="color:gray">(2010-03-09 10:04)</span><br/>· 诺基亚两款概念手机Stealth/Dragonfly曝光<span style="color:gray">(2010-03-09 09:45)</span><br/>· IE6必须死 却没人做得到<span style="color:gray">(2010-03-09 09:41)</span><br/>· 南方日报：QQ的平台化价值是如何创造的？<span style="color:gray">(2010-03-09 09:29)</span><br/></p><p>编辑推荐：史上最强女游戏程序员<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47279</link>
<title><![CDATA[Windows Mobile使用.NET Compact Framework开发多线程程序]]></title>
<author>Jake Lin</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-9 7:06:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47279</guid>
<description><![CDATA[ <p>阅读: 479 评论: 8 作者: Jake Lin 发表于 2010-03-09 07:06 原文链接</p><h1>背景</h1>
<p>多任务成为计算机哪怕是智能设备基本的功能，iPhone不支持多任务一直为使用者所鄙视。以Windows Embedded CE作为基础的Windows Mobile从系统层就支持多任务，其中表现为多线程和多进程。从泄漏的文档看，Windows Phone 7 Series 还是一如既往的支持多任务。</p>
<p>&nbsp;</p>
<h1>简介</h1>
<p>虽然说经济危机过去，经济开始回暖，失业率下降，可是工作还是不太好找，特别是Windows Embedded CE和Windows Mobile等相关嵌入式和移动智能设备的工作买少见少。在最近零星的面试中问及比较多的其中一个问题是多线程的开发。因此这个long weekend把多线程的程序总结一下，为后续的面试做准备。</p>
<p>&nbsp;</p>
<h1>实现</h1>
<h2>开发环境</h2>
<p><img style="border-width: 0px; width: 269px; display: inline; height: 354px;" title="mutilthreading-net-compact-framework-1" alt="mutilthreading-net-compact-framework-1" src="http://images.cnblogs.com/cnblogs_com/procoder/WindowsLiveWriter/WindowsMobile.NETCompactFramework_82F3/mutilthreading-net-compact-framework-1_thumb.png" border="0" width="269" height="354" /></p>
<p>&nbsp;<img style="border-width: 0px; width: 263px; display: inline; height: 348px;" title="mutilthreading-net-compact-framework-2" alt="mutilthreading-net-compact-framework-2" src="http://images.cnblogs.com/cnblogs_com/procoder/WindowsLiveWriter/WindowsMobile.NETCompactFramework_82F3/mutilthreading-net-compact-framework-2_thumb.png" border="0" width="263" height="348" /> </p>
<p>&nbsp;Environment: Visual Studio 2008 + .NET Compact Framework + C# 3.0 + Windows Mobile 5.0 R2 professional (VS 2008 built-in)</p>
<p>&nbsp;</p>
<h2>Start threads</h2><pre class="code"><span style="color: blue;">private void </span>StartThreading()<br />{<br />    UpdateMessageList(<span style="color: #a31515;">"Start threading..."</span>);<br />    menuItem1.Text = <span style="color: #a31515;">"Stop"</span>;<br />    started = <span style="color: blue;">true</span>;<br /><br />    <span style="color: #2b91af;">Thread </span>handlerThread = <span style="color: blue;">new </span><span style="color: #2b91af;">Thread</span>(HanlderThreadProc);    <span style="color: green;">//use delegate ThreadStart to start a new handler thread <br />    </span><span style="color: #2b91af;">Thread </span>requtesterThread = <span style="color: blue;">new </span><span style="color: #2b91af;">Thread</span>(RequesterThreadProc);  <span style="color: green;">//Start a new requester thread<br />    </span>handlerThread.Name = <span style="color: #a31515;">"Hanlder"</span>;<br />    requtesterThread.Name = <span style="color: #a31515;">"Requtester"</span>;<br />    handlerThread.Start();<br />    requtesterThread.Start();<br />}</pre>
<p>Start two threads, one is requester that is responsible to send request and the other is handler thread which is used to handle the request.</p>
<p>启动两个线程，一个负责发请求，一个负责处理请求。</p>
<p>&nbsp;</p>
<h2>Requester thread</h2><pre class="code"><span style="color: green;">//Requester thread<br /></span><span style="color: blue;">private void </span>RequesterThreadProc()<br />{<br />    <span style="color: blue;">int </span>i = 0;<br />    <span style="color: blue;">string </span>messageBody = <span style="color: #a31515;">".NET"</span>;<br />    <span style="color: blue;">while </span>(started)<br />    {<br />        <span style="color: blue;">if </span>(i &gt; 1000)<br />        {<br />            i = 0;<br />        }<br /><br />        <span style="color: #2b91af;">Message </span>msg = <span style="color: blue;">new </span><span style="color: #2b91af;">Message</span>(i, messageBody);<br />        <br />        <span style="color: green;">//lock when try to access shared resource.<br />        </span><span style="color: blue;">lock </span>(lockObj)<br />        {<br />            messageList.Add(msg);<br />        }<br />        <span style="color: blue;">string </span>s = <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"{0} - {1} - {2}"</span>, <span style="color: #2b91af;">Thread</span>.CurrentThread.Name, msg.ID, msg.MessageBody);<br />        UpdateMessageList(s);<br />        autoEvent.Set();<br /><br />        ++i;<br />        <span style="color: #2b91af;">Thread</span>.Sleep(500);<br />    }<br />}</pre>
<p>Instantiate a new Message object and put into the shared container &#8220;messageList&#8221;. Use lock() function to lock the shared resource and use autoEvent to wake up handler thread. At the same time, display the thread name and the Message information to list control.</p>
<p>请求线程负责申请请求对象(Message)然后把请求放进共享资源(messageList)。访问共享资源的时候通过lock函数来锁定。把请求放进list以后，使用autoEvent 去唤醒处理线程。在此同时把请求信息显示到list控件上。</p>
<p>&nbsp;</p>
<h2>Handler thread</h2><pre class="code"><span style="color: green;">//Handler thread<br /></span><span style="color: blue;">private void </span>HanlderThreadProc()<br />{<br />    <span style="color: blue;">while </span>(started)<br />    {<br />        <span style="color: green;">//Only one thread at a time can enter.Wait until it is safe to enter.<br />        </span>autoEvent.WaitOne();<br />        <span style="color: blue;">if </span>(!started)<br />        {<br />            <span style="color: green;">//If the the thread should be quit, return immediately.<br />            </span><span style="color: blue;">return</span>;<br />        }<br /><br />        <span style="color: green;">//Use temp list to decrease the lock duration.<br />        </span><span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">Message</span>&gt; tempMessageList = <span style="color: blue;">new </span><span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">Message</span>&gt;();<br />        <br />        <span style="color: green;">//lock when try to access shared resource.<br />        </span><span style="color: blue;">lock </span>(lockObj)<br />        {<br />            <span style="color: green;">//Access shared resource, messageList in the case.<br />            </span><span style="color: blue;">foreach </span>(<span style="color: #2b91af;">Message </span>msg <span style="color: blue;">in </span>messageList)<br />            {<br />                tempMessageList.Add(msg);<br />            }<br />            <span style="color: green;">//clear up all the request inside the list.<br />            </span>messageList.Clear();<br />        }<br /><br />        <span style="color: green;">//handle the request now.<br />        </span><span style="color: blue;">foreach </span>(<span style="color: #2b91af;">Message </span>msg <span style="color: blue;">in </span>tempMessageList)<br />        {<br />            <span style="color: blue;">string </span>s = <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"{0} - {1} - {2}"</span>, <span style="color: #2b91af;">Thread</span>.CurrentThread.Name, msg.ID, msg.MessageBody);<br />            UpdateMessageList(s);<br />        }<br />    }<br />}</pre>
<p>Handler thread would be in sleep until get the wake up event. Use lock() function to lock the shared resource and use temporary list to store the requests to reduce the lock duration. When process the request, only display the thread name and the Message information to list control. Usually, I would like to use polymorphism. Use different request handle function in derided classes which have the same interface (Template Methods pattern).</p>
<p>处理线程会一直sleep直到得到唤醒消息。访问共享资源的时候同样适用lock函数加锁。为了减少锁的时间，我偏向于使用临时容器把所有请求先缓存下来，在这个例子中，仅仅把请求信息打印到list控件，在实际运用中，我通常通过多态的方法，使用Template Methods模式来处理请求。</p>
<p>&nbsp;</p>
<p>源代码： http://files.cnblogs.com/procoder/ThreadingDemo.zip</p><p>欢迎大家拍板，拍的越多，我改的越好，这样我后面的面试就更有把握了，谢谢！&nbsp;</p><p>&nbsp;</p><img src="http://www.cnblogs.com/procoder/aggbug/1681221.html?type=1" width="1" height="1" alt=""/><p>评论: 8　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· Mochi Media与盛大游戏成立游戏开发者基金<span style="color:gray">(2010-03-09 10:06)</span><br/>· 淘宝启动24小时自助维权平台<span style="color:gray">(2010-03-09 10:04)</span><br/>· 诺基亚两款概念手机Stealth/Dragonfly曝光<span style="color:gray">(2010-03-09 09:45)</span><br/>· IE6必须死 却没人做得到<span style="color:gray">(2010-03-09 09:41)</span><br/>· 南方日报：QQ的平台化价值是如何创造的？<span style="color:gray">(2010-03-09 09:29)</span><br/></p><p>编辑推荐：史上最强女游戏程序员<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47280</link>
<title><![CDATA[提高程序员的准入门槛？]]></title>
<author>taowen</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 23:45:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47280</guid>
<description><![CDATA[ <p>阅读: 878 评论: 8 作者: taowen 发表于 2010-03-08 23:45 原文链接</p><p>效仿敏捷宣言，有人也搞了一个软件工艺（Craftsmanship）宣言。在标题的下面是一行小字，提高准入门槛（Raising the bar）。</p>
<p>UncleBob就这个Topic在世界各地发表演讲。他曾经把程序员与医生做比较：既然程序员与医生一样都是提供职业服务（Professional Service），那么他们就应该遵守类似的行为准则。医生在做手术之前需要洗手洗三遍以防止病人被细菌感染，而且需要用特殊的方式内搓三下外搓三下。假如病人说，我不希望你洗手。医生会拒绝这样的要求，因为这是他们的职业准则。程序员给代码做整理，不屈服于客户（在医生例子就是病人）的不合理的时间要求，因为程序员相比客户来说，程序员是职业的（Professional），应该知道什么样才是正确的事情，什么样才是真正为客户好（在医生的例子里就是怎样才能保护病人）。相反，如果我们屈服于时间压力了，没有对代码做整理，没有坚持更广泛的那些&ldquo;正确的事情&rdquo;，那么我们就不是职业的（Professional）。</p>
<p>他在世界各地做演讲之前都会问一个问题，多少人被Bad Code困扰过。结果自然是所有人。然后第二个问题就是，这些Bad Code都是谁写的。他的结论是，我们这个行业充斥了大量的Bad Code，而根源就是有太多不合格的人在从事这个行当。所以，这才有了那标题下的一行小字：提高准入门槛。但是，这有用吗？</p>
<p>我们来看看参加软件工艺北美大会（SCNA）的Speaker名单。假设这些人都是合格的Professional。他们都是在什么样的公司呢？</p>
<p>&nbsp;</p>
<p>1、Small Group 咨询公司或者独立咨询<br />Robert C. Martin，Michael Feathers ～ Object Mentor<br />Ken Auer ～ RoleModel Software<br />Ward Cunningham ～ 一个人干的产品 AboutUs.Org，曾经的c2.com<br />Jim Weirich ~ EdgeCase<br />Christopher Avery ～ 貌似独立咨询<br />Cory Foy ~ 独立咨询<br />Kevin Taylor，Dave Hoover ～ obtiva<br />Micah Martin，Paul Pagel ~ 8th Light<br />Carl Erickson ～ AtomicObject<br />2、高Value的产品<br />Fred George ～ TrafficBroker<br />Dave Astels ～ Engine Yard&nbsp;<br />Bobby Norton ~ DRW Trading</p>
<p>&nbsp;</p>
<p>那么所谓的不合格的Professional都在什么公司呢？这个就不用问了。显然不是那些精英咨询公司和高Value的产品公司。他们广泛分布于印度中国的外包企业内，而且这个行当每年都在以更快的速度制造这些不合格的Professional。那如何提高准入门槛呢？</p>
<p>但是有什么门槛好提高的？因为门槛已经在那了。如果你不是合格的Professional，像TrafficBroker，DRW Trading的公司会招聘你吗？如果你不是合格的Professional，UncleBob他自己的咨询公司ObjectMentor会招聘你吗？这是一个金字塔。一个人从塔基进入，先从不规范的民企，最次的外包企业开始，然后到好一些的外包企业，然后开始去做咨询，然后要么独立咨询要么就是被Google的Wave Team挖去，要么就是一帮人聚集到DRW Trading这样的小公司，给资本家写期权模型。如果我们只看塔尖，这个门槛已经在那了。Dan North, Bobby Norton这些人自己的道路，就已经说明了走到塔尖是多么的不容易了。那为什么还要提高准入门槛呢？难道是让Tata这样的外包公司不再招聘不合格的毕业生来堆砌代码？且不说其他方面的可行性。哪里来的合格的毕业生？Professional之所以成为Professional，肯定不是一毕业就是Professional的。那么提高门槛的目的就是不再让毕业生加入到写代码的行列来吗？</p>
<p>如果没有这巨大的塔基，如果没有大量的公司招聘大量的Unprofessional。你们塔尖上的人到哪里去招聘人？我同意Software Craftsmanship强调的价值，但是提高准入门槛却是一个很无聊的事情。关键不在于让谁进来，不让谁进来。而是我们这个行业，如何才让像律师和医生一样提供给毕业生在职的锻炼，而不是两三天买一个证书的培训。按照经济规律，牛人扎堆在了牛人一起，而Unprofessional扎堆在塔基在广大的外包软件公司里。那么我们除了牛人从塔尖向下望，摇头还是摇头。那么我们除了塔基的人向上望，摇头还是摇头。还能有什么其他的结果？</p>
<p>到底是环境造就了这样一批人，还是 这样一批人造就了现在这样一个环境呢？到底是什么让这些product owner相信软件可以由non-professional写出来，继而创造了一个可以创造更多non-professional的环境。是我们，还是他们，还是the damn god？</p><img src="http://www.cnblogs.com/taowen/aggbug/1681166.html?type=1" width="1" height="1" alt=""/><p>评论: 8　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· Mochi Media与盛大游戏成立游戏开发者基金<span style="color:gray">(2010-03-09 10:06)</span><br/>· 淘宝启动24小时自助维权平台<span style="color:gray">(2010-03-09 10:04)</span><br/>· 诺基亚两款概念手机Stealth/Dragonfly曝光<span style="color:gray">(2010-03-09 09:45)</span><br/>· IE6必须死 却没人做得到<span style="color:gray">(2010-03-09 09:41)</span><br/>· 南方日报：QQ的平台化价值是如何创造的？<span style="color:gray">(2010-03-09 09:29)</span><br/></p><p>编辑推荐：史上最强女游戏程序员<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47287</link>
<title><![CDATA[雨林木风OS2.0简体中文版发布 哥们儿来吧！]]></title>
<author>wms521125</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 22:47:15</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47287</guid>
<description><![CDATA[ <p><img border=0 src="http://img.diglog.com/img/2010/3/middle_45a1d845044c41bf8c6cd90abc239ae9.jpg" /></p><br/>雨林木风的一句话：等候环境对他的事业完全有利才动手的人，将永远不会成功。<br/><br/>基于Ubuntu 9.10版本定制，集成OpenOffice3.1办公软件,能打开所有ms office 文件，默认集成经典的Windows主题。<br/><br/>系统需求：<br/><br/> <br/><br/><br/>最小配置 <br/>300 MHz x86 处理器 <br/>128 MB 内存/不少于4 GB 硬盘空间 <br/>兼容 640x480 的显卡<br/><br/>推荐配置 <br/>700 MHz x86 处理器 <br/>兼容 1024x768 分辨率的显卡 <br/>512 MB 内存/8 GB 硬盘空间/声卡<br/><br/>原始链接:http://www.chouyingying.com/sing/2010/03/9.html<br/>diglog链接:http://www.diglog.com/story/technology_linux_332015.html  ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47281</link>
<title><![CDATA[ASP.NET WebForm也玩强类型URL调用之二：PageMethods的基本使用]]></title>
<author>张荣华</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 22:39:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47281</guid>
<description><![CDATA[ <p>阅读: 461 评论: 0 作者: 张荣华 发表于 2010-03-08 22:39 原文链接</p><p>在熟悉了PageMethods的基本介绍后，我们来看一个简单的示例程序，这个示例程序很简单，只有两个网页。第一个页面是客户详情编辑页面，叫做FrtmCustomer.aspx，第二个页面叫做ListCustomer.aspx，用来显示客户列表。虽然这个示例程序很简单，但用来说明PageMethods的基本使用却是很合适的，现在让我们来一步步构建这个示例程序。</p>
<h2>步骤一：创建FrmCustomer页面</h2>
<p>首先我们需要确定安装在VS2008中的PageMethods插件是被激活的。</p>
<h4><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/02.png" /></h4>
<p>然后我们创建一个ASP.NET WebSite项目（当然你也可以创建Web Application)</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/01.png" /></p>
<p>创建网站后，添加一个名叫"<i>FrmCustomer.aspx</i>"新Web Form 。<img src="http://metasapiens.com/PageMethods/tutorial/VS2005/04.png" /></p>
<p>然后在新添加的Web Form中构造一个用来编辑客户ID、姓名、国家的界面，三个文本框的ID分别为txtID,txtName,txtCountry，界面如下：</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/05.png" /></p>
<p>然后我们在后台代码中添加用来完成新建和编辑客户的代码：</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/06.png" /></p>
<p>直到现在我们一直按照标准的方法来实现，还没有和PageMethods产生关系， 但从这一步我们就要用到PageMethods里面的东西了，我们需要给上面的两个方法添加PageMethods属性，这需要引用PageMethods类库（位于PageMethods.dll程序集中）。</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/07.png" /></p>
<p>在添加类库引用时请确保添加的是.NET2.0版本的，在添加完类库引用后，在FrmCustomer的后台类中引入MetaSapiens.PageMethods命名空间。</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/03.png" /></p>
<p>引入命名空间后，在方法上标注PageMethods属性。</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/08.png" /></p>
<p>在标注完属性后，我们还需要做一件事情，就是在页面的Page_Load方法中加入如下代码：<img src="http://metasapiens.com/PageMethods/tutorial/VS2005/09.png" /></p>
<p>然后我们在项目的属性窗口中将PageMethodsEnabled属性设为true.</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/10.png" /></p>
<p>最后我们在配置文件中注册PageMethods的生成提供器（当然如果你选择的是Web Application,这步可以省略）</p>
<p>&lt;?xml version="1.0"?&gt;    <br />&lt;configuration &gt;     <br />&nbsp; &lt;appSettings /&gt;     <br />&nbsp; &lt;system.web&gt;     <br />&nbsp;&nbsp;&nbsp; &lt;compilation debug="true"&gt;     <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;buildProviders&gt;     <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;add     <br />&nbsp;&nbsp;&nbsp; extension=".xml"     <br />type="MetaSapiens.PageMethods.PageMethodsBuildProvider, PageMethods" /&gt;     <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/buildProviders&gt;     <br />&nbsp;&nbsp;&nbsp; &lt;/compilation&gt;     <br />&nbsp; &lt;/system.web&gt;</p>
<p>&lt;/configuration&gt;</p>
<p>在做完了上面所有的操作后，编译代码，PageMethods将会在App_Code目录下自动生成一个叫做PageList.xml的文件，这里面包含了PageMethods要用到的代码，请不要手工编辑它。</p>
<h2>步骤二：引用FrmCustomer页面</h2>
<p>在定义完FrmCustomer页面后我们就需要调用它，一般来说我们我们通过HTML锚标记（&lt;a href=&hellip;&gt; ）或是给ASP.NET HyperLink的NavigateUrl赋一个静态值来调用页面，但是在PageMethods中，我们通过后台代码来调用页面，这会带来编译时检查并保证链接是正确的。</p>
<p>下面让我们在Default.aspx页面中添加一个HyperLink控件</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/12.png" /></p>
<p>在Default.aspx的后台类中加入下面的代码以调用FrmCustomer页面:</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/14.png" /></p>
<p>请注意我们在编写上面的代码时是可以使用智能提示的，所以说使用上面的方式调用页面是简单且有效的，因为我们不但可以利用智能提示知道都有哪些页面和参数，还能使用编译时检查来确保调用是正确的。</p>
<p>做完了上面的步骤后，就可以在浏览器中打开Default.aspx页面来验证了，但是请注意，如果你使用的不是IE浏览器，请不要选择"NTLM Authentication"。</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/29.png" /></p>
<p>&nbsp;</p>
<h2>步骤三：改进FrmCustomer页面</h2>
<p>PageMethods还提供了一些其它的属性，比如我们可以利用ParamRequired属性来声明一个引用类型（比如string）的参数是必须的，我们不能对值类型的参数应用ParamRequired属性，因为值类型的参数值不能为null.</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/16.png" /></p>
<p>在应用了ParamRequired属性的，如果在调用时没有传递值就会引发异常。</p>
<p>如果我们想重定义参数的名称，我们可以使用ParamName属性</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/17.png" /></p>
<p>对些一些类型的参数（如时间型、整型）我们还可以利用ParamFormat属性来定义参数的格式。</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/18.png" /></p>
<h2>步骤四：实现ListCustomer页面</h2>
<p>ListCustomer页面包含了客户的列表，我们新建一个叫做ListCustomer.aspx的Web Form并添加一个DataList控件。<img src="http://metasapiens.com/PageMethods/tutorial/VS2005/19.png" /></p>
<p>然后编辑DataList控件的模板</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/20.png" /></p>
<p>在ItemTemplate中加入一个HyperLink控件</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/21.png" /></p>
<p>然后我们创建用来绑定数据的强类型DataSet</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/23.png" /></p>
<p>&nbsp;</p>
<p>注意我们不需要任何数据连接或是TableAdapter对象，我们只需要定义一个叫做"Customer"的数据表，"Customer"表格有三个字段： CustID (<i>System.Int32</i>), Name (<i>System.String</i>), Country (<i>System.String</i>)。</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/24.png" /></p>
<p>现在让我们来模拟一些数据</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/25.png" /></p>
<p>然后给DataList控件的ItemDataBound事件添加处理程序</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/22.png" /></p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/26.png" /></p>
<p>经过上面的步骤后我们就可以在浏览器中测试ListCustomer页面了。</p>
<h2>更多特性</h2>
<h3>页面基类</h3>
<p>你可能会注意到我们在FrmCustomer的Page_Load事件中调用了<i>PageMethodsEngine.InvokeMethod()</i> 方法，实际上你完全可以将这个调用放到自定义的基类中，或者是直接让你的页面类继承自MetaSapiens.PageMethods.BasePage类中。</p>
<h3>默认方法</h3>
<p>PageMethods还有一个额外的特性叫做默认方法，如果一个页面只有一个方法或是有一个主方法，我们可以在方法上引用[PageMethod(true)]属性来代替[PageMethod]，这样会将方法设为默认方法，其结果是我们在调用方法时不需要在URL上添加参数。</p>
<h3>URL格式化</h3>
<p>如果你在项目中应用了URL重写，你可以提供给PageMethods一个格式化字符串来格式化你的URL，下面是一个示例：<img src="http://metasapiens.com/PageMethods/tutorial/VS2005/27.png" /></p>
<p>上面代码的引用链接一般是" http://myserver/PageMethodsTutorial/Pages/FrmCustomer.aspx?PageMethod=EditCustomer&amp;CustomerID=12"形式的，但当我们像下图一样应用了PageMethods.UrlFormat属性后，链接会变成"http://myserver/PageMethodsTutorial/Customer12.aspx"的形式。</p>
<p><img src="http://metasapiens.com/PageMethods/tutorial/VS2005/28.png" /></p>
<h2>了解更多</h2>
<p>关于PageMethods的更多特性，你可以访问PageMethods的主页。</p>
<div>
<div style="float: left;"><img src="http://images.cnblogs.com/cnblogs_com/zhangronghua/227714/r_t_thumbnail.png" /> </div>
<div id="MySignature">作者：张荣华       <br />出处：http://zhangronghua.cnblogs.com       <br />本文版权归作者和博客园共有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。 </div>
<p>&nbsp;</p>
</div><img src="http://www.cnblogs.com/zhangronghua/aggbug/1681128.html?type=1" width="1" height="1" alt=""/><p>评论: 0　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· Mochi Media与盛大游戏成立游戏开发者基金<span style="color:gray">(2010-03-09 10:06)</span><br/>· 淘宝启动24小时自助维权平台<span style="color:gray">(2010-03-09 10:04)</span><br/>· 诺基亚两款概念手机Stealth/Dragonfly曝光<span style="color:gray">(2010-03-09 09:45)</span><br/>· IE6必须死 却没人做得到<span style="color:gray">(2010-03-09 09:41)</span><br/>· 南方日报：QQ的平台化价值是如何创造的？<span style="color:gray">(2010-03-09 09:29)</span><br/></p><p>编辑推荐：史上最强女游戏程序员<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47282</link>
<title><![CDATA[11.类的构造(2)]]></title>
<author>平凡人生</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 21:54:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47282</guid>
<description><![CDATA[ <p>阅读: 353 评论: 0 作者: 平凡人生 发表于 2010-03-08 21:54 原文链接</p><p><span style="background-color: #ff0000;"><span style="color: #000000;">1.</span></span> 构造器会显示（<span style="color: #003366;">" 我是类A的无参构造器"</span>and<span style="color: #003366;">"我是类B的无参构造器"</span>）</p>
<p>public partial class Form1 : Form<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Form1()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializeComponent();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void Form1_Load(object sender, EventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B b = new B(45);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; class A<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public A()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show(" 我是类A的无参构造器");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; class B:A<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public B()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show("我是类B的无参构造器");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp; }</p>
<p><span style="text-decoration: underline;"><b><span style="background-color: #ff0000;">2.</span></b></span>带有一个参数的构造器会显示（<span style="color: #003366;">" 我是类A的无参构造器"</span>and<span style="color: #003366;">"我是类B的带有一个参数的构造器"</span>）</p>
<p>public partial class Form1 : Form<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Form1()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializeComponent();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void Form1_Load(object sender, EventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B b = new B(45);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; class A<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public A()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show(" 我是类A的无参构造器");&nbsp; //去掉无参构造器会出错<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public A(int i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show("我是类A的带有一个参数的构造器");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; class B:A<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public B()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show("我是类B的无参构造器");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public B(int i):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show("我是类B的带有一个参数的构造器");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }</p>
<p><span style="text-decoration: underline;"><b><span style="background-color: #ff0000;">3.</span></b></span> 如果想显示类A可以用 base关键字会显示（<span style="color: #003366;">"我是类A的带有一个参数的构造器"</span>and<span style="color: #003366;">"我是类B的带有一个参数的构造器"</span>）</p>
<p>&nbsp;public partial class Form1 : Form<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Form1()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializeComponent();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void Form1_Load(object sender, EventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B b = new B(45);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; class A<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public A()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show(" 我是类A的无参构造器");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public A(int i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show("我是类A的带有一个参数的构造器");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; class B:A<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public B()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show("我是类B的无参构造器");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public B(int i):base (i)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show("我是类B的带有一个参数的构造器");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }</p>
<p><span style="text-decoration: underline;"><b><span style="background-color: #ff0000;">4.</span></b></span><span style="background-color: #ff0000;">&nbsp;</span>静态构造器注意的事项（ static constructor )</p>
<p>1.静态构造器在任何实例变量分配之前执行。显示为（<span style="color: #003366;">"我是类A的静态构造器"</span>and<span style="color: #003366;">"100"</span>）</p>
<p>public partial class Form1 : Form<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Form1()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializeComponent();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void Form1_Load(object sender, EventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show(A.i+"");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; class A<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static int i = 100;//<span style="color: #003366;">&ldquo;i&rdquo;为空时; 默认值为0</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static A()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show("我是类A的静态构造器");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public A()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show(" 我是类A的无参构造器");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp; }</p>
<p><span style="text-decoration: underline;"><b><span style="background-color: #ff0000; color: #000000;">5.</span></b></span><span style="color: #000000;"><span style="background-color: #ffffff;">在一个程序的执行过程中</span></span>静态构造器最多只执行一次</p>
<p><span style="color: #ff0000;">（1）<span style="color: #000000;">显示为（</span></span><span style="color: #003366;">"我是类A的静态构造器"</span>and<span style="color: #003366;">" 我是类A的无参构造器"</span><span style="color: #ff0000;"><span style="color: #000000;">）</span></span></p>
<p><span style="color: #ff0000;"></span>public partial class Form1 : Form<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Form1()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializeComponent();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void Form1_Load(object sender, EventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A a = new A();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; class A<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static int i = 100; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static A()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show("我是类A的静态构造器");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public A()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show(" 我是类A的无参构造器");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp; }</p>
<p><span style="color: #ff0000;">（2）</span><span style="color: #ff0000;"><span style="color: #000000;">显示为(</span></span><span style="color: #003366;">"我是类A的静态构造器"</span>and<span style="color: #003366;">" 我是类A的无参构造器"</span>and<span style="color: #003366;">" 我是类A的无参构造器"</span><span style="color: #ff0000;"><span style="color: #000000;">)</span></span></p>
<p>public partial class Form1 : Form<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Form1()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitializeComponent();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void Form1_Load(object sender, EventArgs e)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A a = new A();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A a1 = new A();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; class A<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static int i = 100;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static A()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show("我是类A的静态构造器");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public A()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox.Show(" 我是类A的无参构造器");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp; }</p><img src="http://www.cnblogs.com/xiaolongone/aggbug/1681090.html?type=1" width="1" height="1" alt=""/><p>评论: 0　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· Mochi Media与盛大游戏成立游戏开发者基金<span style="color:gray">(2010-03-09 10:06)</span><br/>· 淘宝启动24小时自助维权平台<span style="color:gray">(2010-03-09 10:04)</span><br/>· 诺基亚两款概念手机Stealth/Dragonfly曝光<span style="color:gray">(2010-03-09 09:45)</span><br/>· IE6必须死 却没人做得到<span style="color:gray">(2010-03-09 09:41)</span><br/>· 南方日报：QQ的平台化价值是如何创造的？<span style="color:gray">(2010-03-09 09:29)</span><br/></p><p>编辑推荐：史上最强女游戏程序员<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47283</link>
<title><![CDATA[设计模式学习总结11 - 行为型6 - TemplateMethod模版方法模式]]></title>
<author>Utopia Coming</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 21:20:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47283</guid>
<description><![CDATA[ <p>阅读: 382 评论: 0 作者: Utopia Coming 发表于 2010-03-08 21:20 原文链接</p><p align="center"><strong style="font-size: 24pt">TemplateMethod模版方法模式(行为型)</strong></p>
<p><strong style="font-size: 14pt">作用</strong></p>
<p>模版方法使算法的具体步骤推迟到子类实现。算法的结构稳定，但是算法内部细分的操作可以在其他地方实现。</p>
<p>Role<br />The&nbsp; Template&nbsp; Method&nbsp; pattern&nbsp; enables&nbsp; algorithms&nbsp; to&nbsp; defer&nbsp; certain&nbsp; steps&nbsp; to&nbsp; subclasses. The structure of the algorithm does not change, but small well-defined parts of its operation are handled elsewhere.</p>
<p><strong style="font-size: 14pt">设计</strong></p>
<p><img height="272" alt="" src="http://images.cnblogs.com/cnblogs_com/utopia/Behavioral-TemplateMethod.JPG" width="406" border="0" /></p>
<p>Algorithm，含有模版方法的类<br />TemplateMethod，模版方法，将其内部的操作退到其他类去实现<br />IPrimitives，模版方法推到其他类的操作接口<br />AnyClass，实现了IPrimitives接口的类<br />Operation，模版方法需要完成操作的一个子方法</p>
<p><strong style="font-size: 14pt">举例</strong></p>
<p>Algorithm，日志管理器<br />TemplateMethod，记录日志<br />IPrimitives，记录日志的操作步骤规范1、获取日志信息；2、拆分信息到各字段；3、将各字段信息存入相应记录媒体<br />AnyClass，各种实现了日志记录步骤的方法<br />Operation，记录日志的操作步骤</p>
<p><strong style="font-size: 14pt">实现</strong></p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<div><!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;System;<br /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;System.Collections.Generic;<br /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;System.Linq;<br /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;System.Text;<br /><br /></span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;Templatemethod<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">interface</span><span style="color: #000000">&nbsp;IPrimitives&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;Operation1();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;Operation2();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Algorithm&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;TemplateMethod(IPrimitives&nbsp;a)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;s&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.Operation1()&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.Operation2();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(s);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;ClassA&nbsp;:&nbsp;IPrimitives&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;Operation1()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">ClassA:Op1&nbsp;</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;Operation2()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">ClassA:Op2&nbsp;</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;ClassB&nbsp;:&nbsp;IPrimitives&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;Operation1()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">ClassB:Op1&nbsp;</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;Operation2()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">ClassB.Op2&nbsp;</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Program<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;Main(</span><span style="color: #0000ff">string</span><span style="color: #000000">[]&nbsp;args)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Algorithm&nbsp;m&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Algorithm();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m.TemplateMethod(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ClassA());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m.TemplateMethod(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ClassB());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.ReadLine();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /></span></div></div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong style="font-size: 14pt">应用场景</strong></p>
<p>当一个算法可以分解出共同的行为模式；</p>
<p>根据每个子类的类型变化操作行为<br />Use the Template Method pattern when&#8230;<br />&#8226;&nbsp; Common behavior can be factored out of an algorithm.<br />&#8226;&nbsp; The behavior varies according to the type of a subclass.</p>
<p>&nbsp;</p>
<p><strong style="font-size: 14pt">总结</strong></p>
<p>Template Method模板方法模式是一种行为型模式。解决某个有稳定的操作结构，但各个子步骤却有很多改变的需求，或者由于固有的原因而无法和任务的整体结构同时实现。 GoF《设计模式》中说道：定义一个操作中的算法的步骤，将一些步骤延迟到子类中实现。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。</p><img src="http://www.cnblogs.com/utopia/aggbug/1681066.html?type=1" width="1" height="1" alt=""/><p>评论: 0　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· Mochi Media与盛大游戏成立游戏开发者基金<span style="color:gray">(2010-03-09 10:06)</span><br/>· 淘宝启动24小时自助维权平台<span style="color:gray">(2010-03-09 10:04)</span><br/>· 诺基亚两款概念手机Stealth/Dragonfly曝光<span style="color:gray">(2010-03-09 09:45)</span><br/>· IE6必须死 却没人做得到<span style="color:gray">(2010-03-09 09:41)</span><br/>· 南方日报：QQ的平台化价值是如何创造的？<span style="color:gray">(2010-03-09 09:29)</span><br/></p><p>编辑推荐：史上最强女游戏程序员<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47284</link>
<title><![CDATA[Asp.net缓存简介]]></title>
<author>CareySon</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 21:15:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47284</guid>
<description><![CDATA[ <p>阅读: 1075 评论: 6 作者: CareySon 发表于 2010-03-08 21:15 原文链接</p><h2><strong><font color="#ff8000"></font></strong></h2>  <h2><strong><font color="#ff8000">概述</font></strong></h2>  <p>&#160;&#160;&#160;&#160; 缓存学术一些的解释是”将常用数据放入易于读取的地方以提高性能”。而对于Asp.net来说，需要被缓存的对象多种多样，包括从数据库中提取出来的数据，以及aspx页面生成的静态页，甚至是编译好的程序集。合理利用缓存能让Asp.net的性能大幅提升，下面将对Asp.net中的缓存机制进行简单概述。</p>  <p>&#160;</p>  <h2><strong><font color="#ff8000">缓存的分类</font></strong></h2>  <p>&#160;</p>  <p>&#160;&#160; 在Asp.net中，大部分缓存机制是保存在cache对象中，也就是服务器内存的一部分。当用户请求数据时，如果数据已经被缓存，则用户所提取的数据直接从服务端返回，而不是从数据库等底层数据库提取。这对性能的提升不得不说很有帮助。下面来看asp.net中几种缓存机制。</p>  <p>&#160;</p>  <h3><strong><font color="#ff8000">程序集缓存</font></strong></h3>  <p>&#160;</p>  <p>&#160;&#160;&#160; 简单的说，这种缓存是asp.net自带的，无需开发人员进行参与的缓存方式。即当第一次请求服务器时，Page类以及相关程序集被编译，当下次请求时，访问缓存后的编译而不是重新编译。CLR会自动检测代码的改变，如果代码改变后，当下次访问时，相关代码会被重新编译。</p>  <p>&#160;</p>  <h3><strong><font color="#ff8000">数据源缓存</font></strong></h3>  <p>&#160;</p>  <p>&#160;&#160; 数据源缓存，顾名思义，也就是利用数据源控件对获取的数据进行缓存的方式。这些控件包括SqlDataSource,ObjectDataSource等：</p>  <p>&#160;&#160;&#160; <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="datasource" border="0" alt="datasource" src="http://images.cnblogs.com/cnblogs_com/CareySon/WindowsLiveWriter/Asp.net_11E9A/datasource_thumb.png" width="381" height="378" /> </p>  <p>&#160;&#160; </p>  <p>&#160;&#160;&#160;&#160; 作为抽象类的DataSourceControl暴漏了如下属性用于缓存：</p>  <p>&#160;</p>  <table border="0" cellspacing="0" cellpadding="2" width="676"><tbody>     <tr>       <td valign="top" width="200">名称</td>        <td valign="top" width="474">说明</td>     </tr>      <tr>       <td valign="top" width="200">CacheDuration</td>        <td valign="top" width="474">获取或设置以秒为单位的一段时间，数据源控件就在这段时间内缓存 SelectMethod 属性检索到的数据。</td>     </tr>      <tr>       <td valign="top" width="200">CacheExpirationPolicy</td>        <td valign="top" width="474">获取或设置缓存的到期行为，该行为与持续时间组合在一起可以描述数据源控件所用缓存的行为。</td>     </tr>      <tr>       <td valign="top" width="200">CacheKeyDependency</td>        <td valign="top" width="474">获取或设置一个用户定义的键依赖项，该键依赖项链接到数据源控件创建的所有数据缓存对象。</td>     </tr>      <tr>       <td valign="top" width="200">EnableCaching</td>        <td valign="top" width="474">获取或设置一个值，该值指示 ObjectDataSource 控件是否启用数据缓存。</td>     </tr>   </tbody></table>  <p>&#160;&#160;&#160; </p>  <p>&#160;&#160;&#160;&#160;&#160;&#160; 而使用起来就非常简单了，只需要将缓存的相关属性进行设置即可。比如我想要当前数据源缓存10秒，只需要设置EnableCaching属性和CacheDuration属性如下：</p>  <p>&#160;</p>  <div style="border-bottom: green 1px dashed; border-left: green 3px solid; margin-left: 15px; border-top: green 1px dashed; border-right: green 1px dashed">   <pre><span style="color: #0000ff">&lt;</span><span style="color: #c71585">asp</span>:<span style="color: #800000">SqlDataSource</span> <span style="color: #ff0000">ID</span>=<span style="color: #0000ff">&quot;SqlDataSource1&quot;</span> <span style="color: #ff0000">runat</span>=<span style="color: #0000ff">&quot;server&quot;</span> 
            <span style="color: #ff0000">ConnectionString</span>=<span style="color: #0000ff">&quot;&lt;%$ ConnectionStrings:AdventureWorksConnectionString %&gt;&quot;</span> 
            <span style="color: #ff0000">SelectCommand</span>=<span style="color: #0000ff">&quot;SELECT top 10 * FROM [Person].[Contact]&quot;</span> <strong><span style="color: #ff0000">EnableCaching</span>=<span style="color: #0000ff">&quot;true&quot;</span> <span style="color: #ff0000">CacheDuration</span>=<span style="color: #0000ff">&quot;10&quot;</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span></strong><span style="color: #c71585">asp</span>:<span style="color: #800000">SqlDataSource</span><span style="color: #0000ff">&gt;</span></pre>
</div>

<p>&#160; </p>

<p>这种方式的工作原理可以用下图表示：</p>

<p>&#160;</p>

<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="3" border="0" alt="3" src="http://images.cnblogs.com/cnblogs_com/CareySon/WindowsLiveWriter/Asp.net_11E9A/3_thumb.png" width="491" height="559" /></p>

<p>&#160;</p>

<p></p>

<p>关于ObjectDataSource我推荐阅读Caching Data with the ObjectDataSource</p>

<p>&#160;</p>

<h4><strong><font color="#ff8000">SQL Cache Dependency</font></strong></h4>

<p>&#160;</p>

<p>&#160;&#160;&#160;&#160; 大家应该注意到了上面的数据源控件还暴漏了CacheKeyDependency属性，这是用于实现SQL Cache Dependency的方式，关于Dependency,其实就是在数据库表内容改变时，将相应的缓存进行更新，正如Dependency这个词的意思一样，是缓存依赖底层数据库。下面就要说到两种实现SQL Cache Dependency的方法了。</p>

<p><strong><font color="#ff8000">方法一：使用轮流查询机制（polling-based）：</font></strong></p>

<p><font color="#ff8000"><strong>&#160;&#160;&#160;&#160; </strong></font><font color="#000000">这种方式实现机制是在sql server中插入以AspNet_SqlCacheNotification_Trigger开头的一个特殊的表和5个存储过程，当被监测的表数据发生改变时，则一个名为AspNet_SqlCacheTablesForChangeNotification的表被更新，而Asp.net程序会根据用户设置的间隔时间每隔一定时间检查一下数据库内容是否更新，如果更新，则将缓存中的数据进行跟新。</font></p>

<p>&#160;&#160;&#160;&#160;&#160; 这种机制配置相对比较麻烦。具体做法网上有很多教程，这里我推荐阅读:Using SQL Cache Dependencies.</p>

<p>&#160;&#160;&#160;&#160;&#160; 使用起来就很简单了，可以在页面头部的OutputCache指令中设置，会社DataSource空间中进行设置，设置格式为：“数据库名：表名”.里面的表名即是需要监测是否改变的表名，示例如下：</p>

<div style="border-bottom: green 1px dashed; border-left: green 3px solid; margin-left: 15px; border-top: green 1px dashed; border-right: green 1px dashed">
  <pre><span style="background-color: #ffff00; color: black">&lt;%@ OutputCache Duration=&quot;30&quot; VaryByParam=&quot;none&quot; SqlDependency=&quot;DatabaseName:tableName&quot; %&gt;</span> </pre>
</div>

<p>&#160;&#160;&#160; 如果需要添加多个表，则用”;”进行分割</p>

<div style="border-bottom: green 1px dashed; border-left: green 3px solid; margin-left: 15px; border-top: green 1px dashed; border-right: green 1px dashed">
  <pre>SqlDependency=&quot;<span style="color: #8b0000">database:table;database:table</span>&quot;</pre>
</div>

<p></p>

<p></p>

<p>&#160;</p>

<p><strong><font color="#ff8000">方法二：使用通知机制(notification-based)</font></strong></p>

<p><strong><font color="#ff8000"></font></strong></p>

<p><font color="#ff8000"><strong>&#160;&#160;&#160;&#160;&#160; </strong></font><font color="#000000">使用通知机制配置起来要简便很多，但是sql server的版本需要9.0以上，也就是sql server 2005,使用这种方式需要将sql server的通知服务开启。</font></p>

<p>&#160;&#160;&#160;&#160;&#160; 使用通知机制可以对页面进行缓存，也可以对datasouce控件进行缓存，对页面进行缓存代码如下：</p>

<div style="border-bottom: green 1px dashed; border-left: green 3px solid; margin-left: 15px; border-top: green 1px dashed; border-right: green 1px dashed">
  <pre><span style="background-color: #ffff00; color: black">&lt;%@ OutputCache Duration=&quot;30&quot; VaryByParam=&quot;none&quot; SqlDependency=&quot;CommandNotification&quot; %&gt;</span></pre>
</div>

<p>&#160;&#160; 注意SqlDependency必须设置成CommandNotification。</p>

<p>&#160;&#160; 对于datasource控件，也是同样：</p>

<div style="border-bottom: green 1px dashed; border-left: green 3px solid; margin-left: 15px; border-top: green 1px dashed; border-right: green 1px dashed">
  <pre>        <span style="color: #0000ff">&lt;</span><span style="color: #c71585">asp</span>:<span style="color: #800000">SqlDataSource</span> <span style="color: #ff0000">ID</span>=<span style="color: #0000ff">&quot;SqlDataSource1&quot;</span> <span style="color: #ff0000">runat</span>=<span style="color: #0000ff">&quot;server&quot;</span> 
            <span style="color: #ff0000">ConnectionString</span>=<span style="color: #0000ff">&quot;&lt;%$ ConnectionStrings:AdventureWorksConnectionString %&gt;&quot;</span> 
            <span style="color: #ff0000">SelectCommand</span>=<span style="color: #0000ff">&quot;SELECT top 10 * FROM [Person].[Contact]&quot;</span> <span style="color: #ff0000">EnableCaching</span>=<span style="color: #0000ff">&quot;true&quot;</span> <span style="color: #ff0000">CacheDuration</span>=<span style="color: #0000ff">&quot;10&quot;</span> <span style="color: #ff0000">SqlCacheDependency</span>=<span style="color: #0000ff">&quot;CommandNotification&quot;</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #c71585">asp</span>:<span style="color: #800000">SqlDataSource</span><span style="color: #0000ff">&gt;</span></pre>
</div>

<p>&#160;</p>

<p>&#160;</p>

<h3><strong><font color="#ff8000">输出缓存（output Caching）</font></strong></h3>

<p>&#160;</p>

<p>&#160;&#160;&#160;&#160;&#160; 输出缓存是页面级别的缓存，是将aspx页面内容在第一次请求后生成的静态页放入缓存，在不过期时间内每一次请求时从缓存中返回静态页，而不是重新走完Asp.net的生命周期。可以将可以通过在页面头部加入OutputCache指令实现，也可以通过HttpCachePolicy类实现。</p>

<p>&#160;&#160;&#160;&#160;&#160; 输出缓存可以缓存整个页面，也可以缓存部分页面，缓存页面的一部分是通过用户控件来实现。</p>

<p>&#160;&#160;&#160;&#160;&#160; </p>

<p>&#160;&#160;&#160;&#160;&#160; 下面来看通过OutputCache指令实现页面缓存:</p>

<p>&#160;&#160;&#160;&#160;&#160;&#160; 前面已经看到，这种方式十分简单，下面说一下OutputCache的重点属性</p>

<p>&#160;</p>

<p><strong><font color="#ff8000">Duration</font></strong></p>

<p>&#160;&#160;&#160;&#160; 页面过期的时间，单位为秒。超过过期时间后，则在下一次请求时页面会重新生成并缓存。</p>

<p>&#160;</p>

<p><strong><font color="#ff8000">VaryByHeader</font></strong></p>

<p><strong><font color="#ff8000">VaryByCustom</font></strong></p>

<p><strong><font color="#ff8000">VaryByParam</font></strong></p>

<p><strong><font color="#ff8000">VaryByControl</font></strong></p>

<p><strong><font color="#ff8000">VaryByContentEncodings</font></strong></p>

<p><font color="#ff8000"><strong>&#160;&#160;&#160;&#160;&#160; </strong></font><font color="#000000">这些属性都是为了保存页面的多个版本，比如说一个页面用于显示产品，则根据产品id的不同，缓存同一个页面的不同版本，具体的意思请看MSDN</font></p>

<p>&#160;</p>

<p><strong><font color="#ff8000">CacheProfile</font></strong></p>

<p><font color="#ff8000"><strong>&#160;&#160;&#160;&#160;&#160; </strong></font><font color="#000000">这个选项有些像连接字符串,作用只是将具体的缓存选项变成对于选项的引用，比如我们在Web.Config放入如下代码：</font></p>

<div style="border-bottom: green 1px dashed; border-left: green 3px solid; margin-left: 15px; border-top: green 1px dashed; border-right: green 1px dashed">
  <pre><span style="color: #0000ff">&lt;</span><span style="color: #800000">caching</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;</span><span style="color: #800000">outputCacheSettings</span><span style="color: #0000ff">&gt;</span>
          <span style="color: #0000ff">&lt;</span><span style="color: #800000">outputCacheProfiles</span><span style="color: #0000ff">&gt;</span>
            <span style="color: #0000ff">&lt;</span><span style="color: #800000">add</span> <span style="color: #ff0000">name</span>=<span style="color: #0000ff">&quot;CacheProfile&quot;</span>
                  <span style="color: #ff0000">enabled</span>=<span style="color: #0000ff">&quot;true&quot;</span>
                  <span style="color: #ff0000">duration</span>=<span style="color: #0000ff">&quot;60&quot;</span>
                   <span style="color: #ff0000">varyByParam</span>=<span style="color: #0000ff">&quot;product:id&quot;</span><span style="color: #0000ff">/&gt;</span>
          <span style="color: #0000ff">&lt;/</span><span style="color: #800000">outputCacheProfiles</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;/</span><span style="color: #800000">outputCacheSettings</span><span style="color: #0000ff">&gt;</span>
            
       
      <span style="color: #0000ff">&lt;/</span><span style="color: #800000">caching</span><span style="color: #0000ff">&gt;</span></pre>
</div>&#160;&#160;&#160; <p></p>

<p>&#160;</p>

<p>&#160; 则在引用时只需要在页面头部设置如下:</p>

<div style="border-bottom: green 1px dashed; border-left: green 3px solid; margin-left: 15px; border-top: green 1px dashed; border-right: green 1px dashed">
  <pre><span style="background-color: #ffff00; color: black">&lt;%@ OutputCache CacheProfile=&quot;CacheProfile&quot; %&gt;</span></pre>
</div>

<p>&#160;</p>

<p>&#160; 而不是全部写入页面</p>

<p>&#160;</p>

<p><strong><font color="#ff8000">DiskCacheable</font></strong></p>

<p>&#160;&#160;&#160;&#160; </p>

<p>&#160;&#160;&#160;&#160; 因为服务器内存是有限的，所以通过将DiskCacheable属性设置为true，则可以将缓存页面放入硬盘中，这样即使服务器崩溃重启，缓存依然存在.</p>

<p>&#160;</p>

<p>&#160;</p>

<h4><strong><font color="#ff8000">缓存部分页面</font></strong></h4>

<p>&#160;&#160;&#160;&#160;&#160; 缓存页面的一部分实现原理和缓存整个页面毫无二致，都是在页面头部加入OutputCache指令，唯一的不同是缓存部分页面是在用户控件中进行的。这部分就不在多说了。</p>

<p>&#160;</p>

<h4><strong><font color="#ff8000">使用HttpCachePolicy缓存页面</font></strong></h4>

<p>&#160;</p>

<p>&#160;&#160;&#160;&#160;&#160;&#160; 前面已经说了通过OutputCache指令在页面头部设置缓存选项，另一种替代方法是使用HttpCachePolicy类，这个类的实例是Response.Cache.如果使用HttpCachePolicy设置缓存，则需要在页面移除OutputCache指令。</p>

<p>&#160;&#160;&#160;&#160;&#160; 比如:</p>

<div style="border-bottom: green 1px dashed; border-left: green 3px solid; margin-left: 15px; border-top: green 1px dashed; border-right: green 1px dashed">
  <pre><span style="background-color: #ffff00; color: black">&lt;%@ OutputCache  Duration=&quot;30&quot; VaryByParam=&quot;state;city&quot; %&gt;</span></pre>
</div>

<p>&#160;&#160;&#160; 和下面代码是等价的：</p>

<div style="border-bottom: green 1px dashed; border-left: green 3px solid; margin-left: 15px; border-top: green 1px dashed; border-right: green 1px dashed">
  <pre> 	Response.Cache.SetExpires(DateTime.Now.AddSeconds(30));
      Response.Cache.VaryByParams[&quot;<span style="color: #8b0000">state</span>&quot;] = <span style="color: #0000ff">true</span>;
      Response.Cache.VaryByParams[&quot;<span style="color: #8b0000">city</span>&quot;] = <span style="color: #0000ff">true</span>;</pre>
</div>

<p>&#160; </p>

<p>&#160;&#160; 更多关于HttpCachePolicy，请查看MSDN</p>

<p>&#160;</p>

<h3><strong><font color="#ff8000">对象缓存</font></strong></h3>

<p>&#160;&#160;&#160;&#160;&#160;&#160; 对象缓存是将继承与System.Object的对象缓存在服务器的内存中，通过Page类的Cache属性可以访问到Cache集合。Cache内可以放任何类型的对象，但是要小心使用Cache,因为Cache是占用服务器内存，如果使用不当，也许会拖累性能。</p>

<p>&#160;&#160;&#160;&#160;&#160; 使用Cache的例子：</p>

<div style="border-bottom: green 1px dashed; border-left: green 3px solid; margin-left: 15px; border-top: green 1px dashed; border-right: green 1px dashed">
  <pre>        <span style="color: #008000">//save object into Cache</span>
        Cache[&quot;<span style="color: #8b0000">table</span>&quot;] = GridView1;

        <span style="color: #008000">//get object from Cache</span>
        GridView gv = (GridView)Cache[&quot;<span style="color: #8b0000">table</span>&quot;];</pre>
</div>

<p></p>

<p>&#160;</p>

<p>&#160;&#160; 要注意的是，再提取缓存中的对象时，一定别忘了强制转换。</p>

<p>&#160;</p>

<p>&#160;</p>

<h2><strong><font color="#ff8000">总结</font></strong></h2>

<p>&#160;&#160;&#160;&#160; 文中对Asp.net的缓存机制进行了简述，asp.net中的缓存极大的简化了开发人员的使用。如果使用得当，程序性能会有客观的提升。</p><img src="http://www.cnblogs.com/CareySon/aggbug/1681063.html?type=1" width="1" height="1" alt=""/><p>评论: 6　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· Mochi Media与盛大游戏成立游戏开发者基金<span style="color:gray">(2010-03-09 10:06)</span><br/>· 淘宝启动24小时自助维权平台<span style="color:gray">(2010-03-09 10:04)</span><br/>· 诺基亚两款概念手机Stealth/Dragonfly曝光<span style="color:gray">(2010-03-09 09:45)</span><br/>· IE6必须死 却没人做得到<span style="color:gray">(2010-03-09 09:41)</span><br/>· 南方日报：QQ的平台化价值是如何创造的？<span style="color:gray">(2010-03-09 09:29)</span><br/></p><p>编辑推荐：史上最强女游戏程序员<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47288</link>
<title><![CDATA[这里的鞋你敢穿几双？(胆小者勿入)]]></title>
<author>uygnaf</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 20:02:23</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47288</guid>
<description><![CDATA[ <p><img border=0 src="http://img.diglog.com/img/2010/3/middle_0b4f793872bc4364a38dadc424c907fa.jpg" /></p><br/>这里的鞋你敢穿几双？(胆小者勿入)<br/><br/>原始链接:http://xiabuy.com/2010/03/xie-ni-gan-chuan-ji-shuang.html<br/>diglog链接:http://www.diglog.com/story/life_fashion_332002.html  ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47285</link>
<title><![CDATA[MSSQL 将数据库从国内搬移到国外简单方法]]></title>
<author>天天</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 20:01:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47285</guid>
<description><![CDATA[ <p>阅读: 746 评论: 3 作者: 天天 发表于 2010-03-08 20:01 原文链接</p><p>最近，将网站从国内网站搬移到了Lunarpage，程序转移比较简单，使用cuteftp上传上去就可以了。但是数据库转移一直都是很棘手的一个问题。本文介绍数据库转移的方法。</p>
<p>数据库转移最简单的方法是使用DTS，但是Lunarpages数据库不支持远程数据库链接，所以无法使用DTS，因此只好使用publishing转移数据。</p>
<p>具体步骤如下：</p>
<p><strong>Step1.&nbsp;运行&nbsp;SqlPubWiz.exe</strong></p>
<p class="p0">Publishing类似MS&nbsp;SQL的一个插件，你可以到</p>
<p class="p0">http://www.microsoft.com/downloads/details.aspx?FamilyId=56E5B1C5-BF17-42E0-A410-371A838E570A</p>
<p class="p0">下载，运行后可以在tools下找到</p>
<p class="p0"><img src="http://pic002.cnblogs.com/img/mqingqing123/201003/2010030819534125.jpg" /></p>
<p class="p0">&nbsp;</p>
<p class="p0"><strong>Step2 运行后，会出现运行向导，找到本地数据库</strong></p>
<p class="p0"><img src="http://pic002.cnblogs.com/img/mqingqing123/201003/2010030819522616.png" /></p>
<p class="p0">&nbsp;</p>
<p class="p0"><strong>Step3.选项要生成的类型，系统会自动检测可用内容，一般之选择&ldquo;表&rdquo;&ldquo;存储过程&rdquo;和&ldquo;视图&rdquo;，对于<span style="color: #888888;">Users</span>就不要让系统生成了</strong></p>
<p><img src="http://pic002.cnblogs.com/img/mqingqing123/201003/2010030819551282.png" /></p>
<p>&nbsp;</p>
<p class="p0">点击Next，一直完成。</p>
<p class="p0">&nbsp;</p>
<p class="p0">&nbsp;</p>
<p class="p0"><strong>更改数据库拥有者</strong></p>
<p class="p0"><strong><span style="color: #ff0000;">以下是核心，非常重要，否则不会成功。</span></strong></p>
<p class="p0"><strong><span style="color: #ff0000;">在我们使用网站时，通常会使用SP给我们的账户，例如我原来的数据库叫做&nbsp;&ldquo;bf4190_&rdquo;</span></strong></p>
<p class="p0"><strong><span style="color: #ff0000;">当时网站供应商给我的账户为&nbsp;bf419，则系统生成的数据表如下</span></strong></p>
<p class="p0"><img src="http://pic002.cnblogs.com/img/mqingqing123/201003/2010030819561893.jpg" /></p>
<p class="p0">&nbsp;</p>
<p class="p0">你可以看到，有的表前面有前缀bf419，有的有前缀dbo&nbsp;（db哦，是database&nbsp;owner），这很不同。因为在我们建立表时，脚本的写法略有区别</p>
<p class="p0">&nbsp;</p>
<p class="p0">&nbsp;</p>
<p class="p0">写法一：</p>
<p class="p0"><strong>CREATE&nbsp;TABLE&nbsp;[dbo].[ads]</strong>&nbsp; (</p>
<p class="p0">[id]&nbsp;[int]&nbsp;IDENTITY(1,1)&nbsp;NOT&nbsp;NULL,</p>
<p class="p0">[name]&nbsp;[nvarchar](200)&nbsp;COLLATE&nbsp;SQL_Latin1_General_CP1_CI_AS&nbsp;NULL,</p>
<p class="p0">[img]&nbsp;[nvarchar](200)&nbsp;COLLATE&nbsp;SQL_Latin1_General_CP1_CI_AS&nbsp;NULL,</p>
<p class="p0">}</p>
<p class="p0">&nbsp;</p>
<p class="p0">&nbsp;</p>
<p class="p0">写法二：</p>
<p class="p0"><strong>CREATE&nbsp;TABLE&nbsp;[ads]</strong>&nbsp;&nbsp; (</p>
<p class="p0">[id]&nbsp;[int]&nbsp;IDENTITY(1,1)&nbsp;NOT&nbsp;NULL,</p>
<p class="p0">[name]&nbsp;[nvarchar](200)&nbsp;COLLATE&nbsp;SQL_Latin1_General_CP1_CI_AS&nbsp;NULL,</p>
<p class="p0">[img]&nbsp;[nvarchar](200)&nbsp;COLLATE&nbsp;SQL_Latin1_General_CP1_CI_AS&nbsp;NULL,</p>
<p class="p0">&nbsp;</p>
<p class="p0">}</p>
<p class="p0">&nbsp;</p>
<p class="p0">对于第一种，生成的表就是&nbsp;dbo.ads,&nbsp;而第二个表则是&nbsp;bf419.ads,因为你的bf419其实就是dbo，所以系统可以运行。</p>
<p class="p0">&nbsp;但是，当你把数据库转移到新的服务商时，如果你的账户叫做XXXX，则上面建立bf419.ads则出现错误，而用&nbsp;dbo.ads&nbsp;则完全没有问题。</p>
<p class="p0">&nbsp;通常新旧服务商给用户开的用户名并不一样，所以我们需要更改一下数据库的所有者。</p>
<p class="p0">接下来，用写字板打开，搜索数据库所有者都更改为dbo</p>
<p class="p0"><img src="http://pic002.cnblogs.com/img/mqingqing123/201003/2010030819581416.jpg" /></p>
<p class="p0">&nbsp;</p>
<p class="p0">这样所有的账户都改为dbo，即可。</p>
<p class="p0">下一步，把脚本命名为sqlscript.txt,&nbsp;最好不要叫sqlscript.sql，下面会介绍。</p>
<p class="p0"><strong>然后通过ftp把脚本放到网站的空间。</strong></p>
<p class="p0">&nbsp;</p>
<p class="p0">编写脚本，例如命名为<strong>runsql.aspx</strong> ,然后运行该脚本即可还原数据库</p>
<p class="p0">&nbsp;</p>
<p class="p0">&nbsp;</p>
<p class="p0">&nbsp;</p>
<p class="p0">&lt;%</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Sample&nbsp;code&nbsp;for&nbsp;executing&nbsp;a&nbsp;T-SQL&nbsp;file&nbsp;using&nbsp;an&nbsp;ASP.NET&nbsp;page</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Copyright&nbsp;(C)&nbsp;Microsoft&nbsp;Corporation,&nbsp;2007.&nbsp;&nbsp;All&nbsp;rights&nbsp;reserved.</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Written&nbsp;as&nbsp;a&nbsp;sample&nbsp;with&nbsp;use&nbsp;in&nbsp;conjuction&nbsp;with&nbsp;the&nbsp;SQL&nbsp;Server&nbsp;Database&nbsp;Publishing&nbsp;Wizard</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;For&nbsp;more&nbsp;information&nbsp;visit&nbsp;http://www.codeplex.com/sqlhost/</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;**************************************************************************</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Note:&nbsp;Please&nbsp;ensure&nbsp;that&nbsp;you&nbsp;delete&nbsp;this&nbsp;page&nbsp;once&nbsp;your&nbsp;database&nbsp;has&nbsp;been&nbsp;published&nbsp;to&nbsp;the&nbsp;remote&nbsp;server</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;**************************************************************************</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%&gt;</p>
<p class="p0">&nbsp;</p>
<p class="p0">&lt;%@&nbsp;Page&nbsp;Language="C#"&nbsp;AutoEventWireup="true"&nbsp;&nbsp;%&gt;</p>
<p class="p0">&lt;%@&nbsp;Import&nbsp;Namespace="System.Data"&nbsp;%&gt;</p>
<p class="p0">&lt;%@&nbsp;Import&nbsp;Namespace="System.Data.SqlClient"&nbsp;%&gt;</p>
<p class="p0">&lt;%@&nbsp;Import&nbsp;Namespace="System.IO"&nbsp;%&gt;</p>
<p class="p0">&lt;%@&nbsp;Import&nbsp;Namespace="System.Net"&nbsp;%&gt;</p>
<p class="p0">&nbsp;</p>
<p class="p0">&nbsp;</p>
<p class="p0">&lt;%</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;**************************************************************************</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Update&nbsp;these&nbsp;variables&nbsp;here</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;**************************************************************************</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Url&nbsp;of&nbsp;the&nbsp;T-SQL&nbsp;file&nbsp;you&nbsp;want&nbsp;to&nbsp;run</p>
<p class="p0">&nbsp;&nbsp;&nbsp;<strong><span style="color: #ff0000;">&nbsp;string&nbsp;fileUrl&nbsp;=&nbsp;@"http://www.sohu.com/sqlscript.txt";</span>&nbsp;&nbsp;&nbsp;&nbsp;</strong></p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Connection&nbsp;string&nbsp;to&nbsp;the&nbsp;server&nbsp;you&nbsp;want&nbsp;to&nbsp;execute&nbsp;against</p>
<p class="p0">string&nbsp;connectionString&nbsp;=&nbsp;@"<span style="color: #ff0000;"><strong>Data&nbsp;Source=11.1.1.1;</strong></span></p>
<p class="p0"><span style="color: #ff0000;"><strong>User&nbsp;ID=hdd;Password=dd;Initial&nbsp;Catalog=s603</strong></span>";</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Timeout&nbsp;of&nbsp;batches&nbsp;(in&nbsp;seconds)</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;timeout&nbsp;=&nbsp;20000;</p>
<p class="p0">&nbsp;</p>
<p class="p0">&nbsp;</p>
<p class="p0">&nbsp;%&gt;</p>
<p class="p0">&nbsp;</p>
<p class="p0">&lt;!DOCTYPE&nbsp;html&nbsp;PUBLIC&nbsp;"-//W3C//DTD&nbsp;XHTML&nbsp;1.0&nbsp;Transitional//EN"&nbsp;"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;</p>
<p class="p0">&nbsp;</p>
<p class="p0">&lt;html&nbsp;xmlns="http://www.w3.org/1999/xhtml"&nbsp;&gt;</p>
<p class="p0">&lt;head&nbsp;runat="server"&gt;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;title&gt;Executing&nbsp;T-SQL&lt;/title&gt;</p>
<p class="p0">&lt;/head&gt;</p>
<p class="p0">&lt;body&gt;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;form&nbsp;id="form1"&nbsp;runat="server"&gt;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;div&gt;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;/form&gt;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&lt;%</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SqlConnection&nbsp;conn&nbsp;=&nbsp;null;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Response.Write(String.Format("Opening&nbsp;url&nbsp;{0}&lt;BR&gt;",&nbsp;fileUrl));</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;read&nbsp;file</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WebRequest&nbsp;request&nbsp;=&nbsp;WebRequest.Create(fileUrl);</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using&nbsp;(StreamReader&nbsp;sr&nbsp;=&nbsp;new&nbsp;StreamReader(request.GetResponse().GetResponseStream()))</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Response.Write("Connecting&nbsp;to&nbsp;SQL&nbsp;Server&nbsp;database...&lt;BR&gt;");</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Create&nbsp;new&nbsp;connection&nbsp;to&nbsp;database</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn&nbsp;=&nbsp;new&nbsp;SqlConnection(connectionString);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.Open();</p>
<p class="p0">&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(!sr.EndOfStream)</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StringBuilder&nbsp;sb&nbsp;=&nbsp;new&nbsp;StringBuilder();</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SqlCommand&nbsp;cmd&nbsp;=&nbsp;conn.CreateCommand();</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(!sr.EndOfStream)</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string&nbsp;s&nbsp;=&nbsp;sr.ReadLine();</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(s&nbsp;!=&nbsp;null&nbsp;&amp;&amp;&nbsp;s.ToUpper().Trim().Equals("GO"))</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sb.AppendLine(s);</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p class="p0">&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Execute&nbsp;T-SQL&nbsp;against&nbsp;the&nbsp;target&nbsp;database</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmd.CommandText&nbsp;=&nbsp;sb.ToString();</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmd.CommandTimeout&nbsp;=&nbsp;timeout;</p>
<p class="p0">&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmd.ExecuteNonQuery();</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p class="p0">&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Response.Write("T-SQL&nbsp;file&nbsp;executed&nbsp;successfully");</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch&nbsp;(Exception&nbsp;ex)</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Response.Write(String.Format("An&nbsp;error&nbsp;occured:&nbsp;{0}",&nbsp;ex.ToString()));</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;finally</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Close&nbsp;out&nbsp;the&nbsp;connection</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(conn&nbsp;!=&nbsp;null)</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.Close();</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.Dispose();</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch&nbsp;(Exception&nbsp;e)</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Response.Write(String.Format(@"Could&nbsp;not&nbsp;close&nbsp;the&nbsp;connection.&nbsp;&nbsp;Error&nbsp;was&nbsp;{0}",&nbsp;e.ToString()));</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%&gt;</p>
<p class="p0">&lt;/body&gt;</p>
<p class="p0">&lt;/html&gt;</p>
<p class="p0">&nbsp;</p>
<p class="p0">需要注意</p>
<p class="p0">&nbsp;&nbsp;&nbsp;&nbsp;string&nbsp;fileUrl&nbsp;=&nbsp;@"http://www.sohu.com/sqlscript.txt";&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p class="p0">是用户脚本地址，<strong>因为很多空间禁止获取sql</strong>，所以，改成这样</p>
<p class="p0">string&nbsp;fileUrl&nbsp;=&nbsp;@"http://www.sohu.com/sqlscript.sql";&nbsp;</p>
<p class="p0">系统可能无法运行。</p>
<p class="p0">&nbsp;</p>
<p class="p0">这样，就完成了数据库转移。</p><img src="http://www.cnblogs.com/mqingqing123/aggbug/1681033.html?type=1" width="1" height="1" alt=""/><p>评论: 3　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· Mochi Media与盛大游戏成立游戏开发者基金<span style="color:gray">(2010-03-09 10:06)</span><br/>· 淘宝启动24小时自助维权平台<span style="color:gray">(2010-03-09 10:04)</span><br/>· 诺基亚两款概念手机Stealth/Dragonfly曝光<span style="color:gray">(2010-03-09 09:45)</span><br/>· IE6必须死 却没人做得到<span style="color:gray">(2010-03-09 09:41)</span><br/>· 南方日报：QQ的平台化价值是如何创造的？<span style="color:gray">(2010-03-09 09:29)</span><br/></p><p>编辑推荐：史上最强女游戏程序员<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47286</link>
<title><![CDATA[CLR via C# 3 读书笔记（7）：第1章 CLR执行模型 — 1.7 通用类型系统]]></title>
<author>麒麟.NET</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 17:03:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47286</guid>
<description><![CDATA[ <p>阅读: 630 评论: 0 作者: 麒麟.NET 发表于 2010-03-08 17:03 原文链接</p><p>类型是CLR的基本，微软创建了一个正式的规约&mdash;&mdash;通用类型系统（Common Type System，CTS）来描述类型的定义和行为。</p>
<p>CTS规约规定，类型可以包含0个或多个成员。</p>
<ul>
<li>字段（Field）：属于对象状态部分的数据成员。字段由字段的名称和类型来标识。  </li>
<li>方法（Method）：在对象上执行某种操作的函数，通常会改变对象的状态。方法包含名称、签名和修饰符。签名指定了方法参数的个数（和顺序）、参数的类型以及返回值类型。  </li>
<li>属性（Property）：对调用者来说，属性类似字段。但对类型实现者来说，属性更像一个方法（或两个）。属性允许实现者在访问属性值之前验证输入参数，抑或在必要时进行求值计算。还可以创建只读或只写的&ldquo;字段&rdquo;。  </li>
<li>事件（Event）：事件在一个对象和另一个与之相关联的对象之间建立一个通知机制。</li>
</ul>
<p>CTS还指定了类型可见性和访问类型成员的一些规则。CTS建立了以程序集作为类型可见性边界的规则，CLR遵循了这些可见性规则。</p>
<ul>
<li>Private：该成员只能被同一个类型的其他成员访问。  </li>
<li>Family：该成员可以被派生类型访问，不管派生类型是否与父类位于同一个程序集。许多语言（C++、C#）都使用protected。  </li>
<li>Family and assembly：该成员只能被同一程序集中的派生类访问。许多语言（C#、VB）都没有提供这种访问控制。当然，IL可以做到。  </li>
<li>Assembly：该成员可以被同一程序集中的任何代码访问，许多语言使用internal。  </li>
<li>Family or assembly：该成员可以被任何程序集中的派生类访问，也可以被同一程序集中的任何类型访问。C#使用protected internal。  </li>
<li>Public：该成员可以被任何程序集中的任何代码访问。</li>
</ul>
<p>此外，CTS还定义了管理类型继承、虚拟方法、对象生命周期的规则。设计这些规则的目的是使它们的语义可以用现代编程语言方便地表达出来。</p>
<p>在作者第一次使用CLR的时候，很快就意识到最好将语言和代码的行为区分开来。我们可以使用C++、C#和VB来创建相同的类型和成员，它们的语法不同，但是类型的行为是完全相同的。<strong><span style="color: #008080;">CLR的CTS定义了类型的行为</span></strong>。</p>
<p>例如，CTS规定一个类型只能有一个父类。而C++支持多继承，但CTS不会接受这种类型。对此，当试图创建继承多个基类的类型时（托管代码），C++/CLI编译器会报错。</p>
<p>CTS还有一个规则，所有的类型必须（最终）继承自一个预定义的类型：System.Object。（可以使用/noautoinherit禁用这种默认的继承）该类定义在System命名空间下。System.Object允许执行以下操作：</p>
<ul>
<li>判断两个实例是否相等。  </li>
<li>获得实例的散列码。  </li>
<li>查询实例的类型。  </li>
<li>执行实例的浅拷贝（shallow copy），即按位（bitwise）拷贝。  </li>
<li>获得实例当前状态的字符串表示。</li>
</ul><img src="http://www.cnblogs.com/kirinboy/aggbug/1680943.html?type=1" width="1" height="1" alt=""/><p>评论: 0　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· Mochi Media与盛大游戏成立游戏开发者基金<span style="color:gray">(2010-03-09 10:06)</span><br/>· 淘宝启动24小时自助维权平台<span style="color:gray">(2010-03-09 10:04)</span><br/>· 诺基亚两款概念手机Stealth/Dragonfly曝光<span style="color:gray">(2010-03-09 09:45)</span><br/>· IE6必须死 却没人做得到<span style="color:gray">(2010-03-09 09:41)</span><br/>· 南方日报：QQ的平台化价值是如何创造的？<span style="color:gray">(2010-03-09 09:29)</span><br/></p><p>编辑推荐：史上最强女游戏程序员<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47270</link>
<title><![CDATA[CLR via C# 3 读书笔记（7）：第1章 CLR执行模型 — 1.7 通用类型系统]]></title>
<author>麒麟.NET</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 17:03:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47270</guid>
<description><![CDATA[ <p>阅读: 76 评论: 0 作者: 麒麟.NET 发表于 2010-03-08 17:03 原文链接</p><p>类型是CLR的基本，微软创建了一个正式的规约&mdash;&mdash;通用类型系统（Common Type System，CTS）来描述类型的定义和行为。</p>
<p>CTS规约规定，类型可以包含0个或多个成员。</p>
<ul>
<li>字段（Field）：属于对象状态部分的数据成员。字段由字段的名称和类型来标识。  </li>
<li>方法（Method）：在对象上执行某种操作的函数，通常会改变对象的状态。方法包含名称、签名和修饰符。签名指定了方法参数的个数（和顺序）、参数的类型以及返回值类型。  </li>
<li>属性（Property）：对调用者来说，属性类似字段。但对类型实现者来说，属性更像一个方法（或两个）。属性允许实现者在访问属性值之前验证输入参数，抑或在必要时进行求值计算。还可以创建只读或只写的&ldquo;字段&rdquo;。  </li>
<li>事件（Event）：事件在一个对象和另一个与之相关联的对象之间建立一个通知机制。</li>
</ul>
<p>CTS还指定了类型可见性和访问类型成员的一些规则。CTS建立了以程序集作为类型可见性边界的规则，CLR遵循了这些可见性规则。</p>
<ul>
<li>Private：该成员只能被同一个类型的其他成员访问。  </li>
<li>Family：该成员可以被派生类型访问，不管派生类型是否与父类位于同一个程序集。许多语言（C++、C#）都使用protected。  </li>
<li>Family and assembly：该成员只能被同一程序集中的派生类访问。许多语言（C#、VB）都没有提供这种访问控制。当然，IL可以做到。  </li>
<li>Assembly：该成员可以被同一程序集中的任何代码访问，许多语言使用internal。  </li>
<li>Family or assembly：该成员可以被任何程序集中的派生类访问，也可以被同一程序集中的任何类型访问。C#使用protected internal。  </li>
<li>Public：该成员可以被任何程序集中的任何代码访问。</li>
</ul>
<p>此外，CTS还定义了管理类型继承、虚拟方法、对象生命周期的规则。设计这些规则的目的是使它们的语义可以用现代编程语言方便地表达出来。</p>
<p>在作者第一次使用CLR的时候，很快就意识到最好将语言和代码的行为区分开来。我们可以使用C++、C#和VB来创建相同的类型和成员，它们的语法不同，但是类型的行为是完全相同的。<strong><span style="color: #008080;">CLR的CTS定义了类型的行为</span></strong>。</p>
<p>例如，CTS规定一个类型只能有一个父类。而C++支持多继承，但CTS不会接受这种类型。对此，当试图创建继承多个基类的类型时（托管代码），C++/CLI编译器会报错。</p>
<p>CTS还有一个规则，所有的类型必须（最终）继承自一个预定义的类型：System.Object。（可以使用/noautoinherit禁用这种默认的继承）该类定义在System命名空间下。System.Object允许执行以下操作：</p>
<ul>
<li>判断两个实例是否相等。  </li>
<li>获得实例的散列码。  </li>
<li>查询实例的类型。  </li>
<li>执行实例的浅拷贝（shallow copy），即按位（bitwise）拷贝。  </li>
<li>获得实例当前状态的字符串表示。</li>
</ul><img src="http://www.cnblogs.com/kirinboy/aggbug/1680943.html?type=1" width="1" height="1" alt=""/><p>评论: 0　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· QQ一亿在线背后的摩尔速度<span style="color:gray">(2010-03-08 17:29)</span><br/>· 美科技博客揭秘社交网站Facebook创建过程<span style="color:gray">(2010-03-08 17:21)</span><br/>· 各大网站纷纷推出妇女节专题<span style="color:gray">(2010-03-08 17:14)</span><br/>· 首款iPad游戏《Zen Bound释禅2》截图曝光<span style="color:gray">(2010-03-08 17:09)</span><br/>· 《星际争霸2》韩国遭拒 暴雪转战网吧推广<span style="color:gray">(2010-03-08 17:00)</span><br/></p><p>编辑推荐：2010年3月编程语言排行榜<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47269</link>
<title><![CDATA[Silverlight 版的华容道游戏]]></title>
<author>ghj1976</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 16:15:16</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47269</guid>
<description><![CDATA[ <p>游戏如下：</p> <iframe style="width: 300px; height: 350px" src="http://ghj1976.blob.core.windows.net/silverlight/TestPage_SilverlightApp_HuaRongDao_v1.html" frameborder="0" scrolling="no"></iframe>  <p>&#160;</p>  <p>你也可以访问这个地址来玩：</p>  <p>http://ghj1976.blob.core.windows.net/silverlight/TestPage_SilverlightApp_HuaRongDao_v1.html</p>  <p>游戏说明：</p>  <ul>   <li>游戏共有27关（前25关都是有难度的，最后2关，则是非常简单的）。 </li>    <li>在棋子上按下按钮，拖动棋子时，棋子移动。 </li>    <li>点击关卡名，则可以重新开始本关；关卡名的左右可以前一关，下一关的移动。 </li> </ul>  <p>更多功能可以自己来试玩。</p>  <p>游戏的代码在：</p>  <p>http://ghj1976.blob.core.windows.net/silverlight/Solution_HuaRongDao_v1.zip</p>  <p>是使用 VS2010 Beta编写的，这是我学习Silverlight写的一个例子，代码并不优雅，见谅。</p><br/><hr/>博客堂源代码发布已经发布于Codeplex，邀请您来捉臭虫<img src="http://blog.joycode.com/ajaxhelper.aggbug?PostId=115902&BlogId=64" > ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47271</link>
<title><![CDATA[用jQuery制作模拟下拉框]]></title>
<author>Rainweb</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 14:22:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47271</guid>
<description><![CDATA[ <p>阅读: 942 评论: 7 作者: Rainweb 发表于 2010-03-08 14:22 原文链接</p><h4>第一步：先搭建好结构</h4>
<p>这是普通的下拉框代码：</p>
<div class="codeText">
<div class="codeHead">XML/HTML代码</div>
<ol class="dp-xml"><li class="alt"><span class="tag">&lt;</span><span class="tag-name">select</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"abc"</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"abc"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">option</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"1"</span><span class="tag">&gt;</span><span>选项一</span><span class="tag">&lt;/</span><span class="tag-name">option</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">option</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"2"</span><span class="tag">&gt;</span><span>选项二</span><span class="tag">&lt;/</span><span class="tag-name">option</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">option</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"3"</span><span class="tag">&gt;</span><span>选项三</span><span class="tag">&lt;/</span><span class="tag-name">option</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">option</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"4"</span><span class="tag">&gt;</span><span>选项四</span><span class="tag">&lt;/</span><span class="tag-name">option</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">option</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"5"</span><span class="tag">&gt;</span><span>选项五</span><span class="tag">&lt;/</span><span class="tag-name">option</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">option</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">"6"</span><span class="tag">&gt;</span><span>选项六</span><span class="tag">&lt;/</span><span class="tag-name">option</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li><span class="tag">&lt;/</span><span class="tag-name">select</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li></ol></div>
<p>这个是模拟出来的：</p>
<div class="codeText">
<div class="codeHead">XML/HTML代码</div>
<ol class="dp-xml"><li class="alt"><span class="tag">&lt;</span><span class="tag-name">div</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"CRselectBox"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">input</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"hidden"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">""</span><span>&nbsp;&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"abc"</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"abc"</span><span class="tag">/&gt;</span><span>&nbsp;</span><span class="comments">&lt;!--&nbsp;hidden&nbsp;用来代替select的值&nbsp;--&gt;</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">input</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"hidden"</span><span>&nbsp;</span><span class="attribute">value</span><span>=</span><span class="attribute-value">""</span><span>&nbsp;&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">"abc_CRtext"</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"abc_CRtext"</span><span class="tag">/&gt;</span><span>&nbsp;</span><span class="comments">&lt;!--&nbsp;hidden&nbsp;用来代替select的文本--&gt;</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">a</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"CRselectValue"</span><span>&nbsp;</span><span class="attribute">href</span><span>=</span><span class="attribute-value">"#"</span><span class="tag">&gt;</span><span>选项一</span><span class="tag">&lt;/</span><span class="tag-name">a</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">ul</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"CRselectBoxOptions"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">li</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"CRselectBoxItem"</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">a</span><span>&nbsp;</span><span class="attribute">href</span><span>=</span><span class="attribute-value">"#"</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"selected"</span><span>&nbsp;</span><span class="attribute">rel</span><span>=</span><span class="attribute-value">"1"</span><span class="tag">&gt;</span><span>选项一</span><span class="tag">&lt;/</span><span class="tag-name">a</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">li</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">li</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"CRselectBoxItem"</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">a</span><span>&nbsp;</span><span class="attribute">href</span><span>=</span><span class="attribute-value">"#"</span><span>&nbsp;</span><span class="attribute">rel</span><span>=</span><span class="attribute-value">"2"</span><span class="tag">&gt;</span><span>选项二</span><span class="tag">&lt;/</span><span class="tag-name">a</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">li</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">li</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"CRselectBoxItem"</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">a</span><span>&nbsp;</span><span class="attribute">href</span><span>=</span><span class="attribute-value">"#"</span><span>&nbsp;</span><span class="attribute">rel</span><span>=</span><span class="attribute-value">"3"</span><span class="tag">&gt;</span><span>选项三</span><span class="tag">&lt;/</span><span class="tag-name">a</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">li</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">li</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"CRselectBoxItem"</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">a</span><span>&nbsp;</span><span class="attribute">href</span><span>=</span><span class="attribute-value">"#"</span><span>&nbsp;</span><span class="attribute">rel</span><span>=</span><span class="attribute-value">"4"</span><span class="tag">&gt;</span><span>选项四</span><span class="tag">&lt;/</span><span class="tag-name">a</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">li</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">li</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"CRselectBoxItem"</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">a</span><span>&nbsp;</span><span class="attribute">href</span><span>=</span><span class="attribute-value">"#"</span><span>&nbsp;</span><span class="attribute">rel</span><span>=</span><span class="attribute-value">"5"</span><span class="tag">&gt;</span><span>选项五</span><span class="tag">&lt;/</span><span class="tag-name">a</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">li</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">li</span><span>&nbsp;</span><span class="attribute">class</span><span>=</span><span class="attribute-value">"CRselectBoxItem"</span><span class="tag">&gt;</span><span class="tag">&lt;</span><span class="tag-name">a</span><span>&nbsp;</span><span class="attribute">href</span><span>=</span><span class="attribute-value">"#"</span><span>&nbsp;</span><span class="attribute">rel</span><span>=</span><span class="attribute-value">"6"</span><span class="tag">&gt;</span><span>选项六</span><span class="tag">&lt;/</span><span class="tag-name">a</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">li</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;/</span><span class="tag-name">ul</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span class="tag">&lt;/</span><span class="tag-name">div</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span> </li></ol></div>
<p>查看演示</p>
<h4>第二步：构建效果</h4>
<p>主要就是Jquery代码：</p>
<div class="codeText">
<div class="codeHead">JavaScript代码</div>
<ol class="dp-c"><li class="alt"><span>$(</span><span class="keyword">function</span><span>(){ &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="string">".CRselectBox"</span><span>).hover(</span><span class="keyword">function</span><span>(){ &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="keyword">this</span><span>).addClass(</span><span class="string">"CRselectBoxHover"</span><span>); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;},</span><span class="keyword">function</span><span>(){ &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="keyword">this</span><span>).removeClass(</span><span class="string">"CRselectBoxHover"</span><span>); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="string">".CRselectValue"</span><span>).click(</span><span class="keyword">function</span><span>(){ &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="keyword">this</span><span>).blur(); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="string">".CRselectBoxOptions"</span><span>).show(); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>; &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="string">".CRselectBoxItem&nbsp;a"</span><span>).click(</span><span class="keyword">function</span><span>(){ &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="keyword">this</span><span>).blur(); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">var</span><span>&nbsp;value&nbsp;=&nbsp;$(</span><span class="keyword">this</span><span>).attr(</span><span class="string">"rel"</span><span>); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">var</span><span>&nbsp;txt&nbsp;=&nbsp;$(</span><span class="keyword">this</span><span>).text(); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="string">"#abc"</span><span>).val(value); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="string">"#abc_CRtext"</span><span>).val(txt); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="string">".CRselectValue"</span><span>).text(txt); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="string">".CRselectBoxItem&nbsp;a"</span><span>).removeClass(</span><span class="string">"selected"</span><span>); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="keyword">this</span><span>).addClass(</span><span class="string">"selected"</span><span>); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="string">".CRselectBoxOptions"</span><span>).hide(); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">false</span><span>; &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">/*点击任何地方关闭层*/</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;$(document).click(</span><span class="keyword">function</span><span>(event){ &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>(&nbsp;$(event.target).attr(</span><span class="string">"class"</span><span>)&nbsp;!=&nbsp;</span><span class="string">"CRselectBox"</span><span>&nbsp;){ &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="string">".CRselectBoxOptions"</span><span>).hide(); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">/*===================Test========================*/</span><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;$(</span><span class="string">"#test"</span><span>).click(</span><span class="keyword">function</span><span>(){ &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">var</span><span>&nbsp;value&nbsp;=&nbsp;$(</span><span class="string">"#abc"</span><span>).val(); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">var</span><span>&nbsp;txt&nbsp;=&nbsp;$(</span><span class="string">"#abc_CRtext"</span><span>).val(); &nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(&nbsp;</span><span class="string">"你本次选择的值和文本分别是："</span><span>&nbsp;+&nbsp;value&nbsp;+</span><span class="string">"&nbsp;&nbsp;,&nbsp;"</span><span>+txt&nbsp;); &nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;</span></li><li class="alt"><span>})&nbsp;&nbsp;</span> </li></ol></div>
<p>查看演示</p>
<p>&nbsp;</p>
<p>其实到这里已经算是完成了。为了方便利用，就做成插件吧。</p>
<p>&nbsp;</p>
<p>查看完整版本演示&nbsp;&nbsp;&nbsp;&nbsp; 下载例子</p><img src="http://www.cnblogs.com/rainweb/aggbug/1680774.html?type=1" width="1" height="1" alt=""/><p>评论: 7　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· QQ一亿在线背后的摩尔速度<span style="color:gray">(2010-03-08 17:29)</span><br/>· 美科技博客揭秘社交网站Facebook创建过程<span style="color:gray">(2010-03-08 17:21)</span><br/>· 各大网站纷纷推出妇女节专题<span style="color:gray">(2010-03-08 17:14)</span><br/>· 首款iPad游戏《Zen Bound释禅2》截图曝光<span style="color:gray">(2010-03-08 17:09)</span><br/>· 《星际争霸2》韩国遭拒 暴雪转战网吧推广<span style="color:gray">(2010-03-08 17:00)</span><br/></p><p>编辑推荐：2010年3月编程语言排行榜<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47272</link>
<title><![CDATA[【读文有感】如何半路接手一个软件项目？]]></title>
<author>熊鹰</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 14:08:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47272</guid>
<description><![CDATA[ <p>阅读: 861 评论: 4 作者: 熊鹰 发表于 2010-03-08 14:08 原文链接</p><p><span style="background-color: #c0c0c0;">【案例正文】</span><br />由于前任项目经理高升，同事A被选择做一个进程已过半的项目。 </p>
<p>领导B在任命A做项目经理的时间，介绍说：此项目一切顺利，只要改动一下程序，完成最后一阶段测试就大功告成了。但事实是，<span style="color: #0000ff;">原PM没留下任何文档记录。已完成的工作也没有文档固化下来，结果是客户要求改动的程序不是一点，而是很多，而且本以为原来已完成的部分也有很多遗留问题，尽管B又给A的项目增加了资源，但最后的结果是由于项目范围蔓延严重，没有达到预期的目标。 </span></p>
<p>A受到了领导的批评。麻烦各位专家帮忙分析一下，作为半路接手的项目经理，A做错了什么，他应该怎样做？ </p>
<p>&nbsp;</p>
<p><span style="background-color: #c0c0c0;">【相关分析】</span></p>
<p>&middot;尽显英雄本色(2008-08-22)&nbsp;&nbsp; [作 者] 四季风&nbsp; [公 司] 兴库建设投资有限公司 <br />一是感谢领导给你锻炼的机会。领导B说的你是否了解清楚？是否你接手后仔细的向前任请教过资料等事情，是否你说话时偏挑剔。<br />二是喜欢困难工作。越是大家认为难以完成的越要努力完成，你可以召开项目会议，鼓励大家创造条件的干好工作，并主动说明请A继续协助一段时间。<br />三是少说困难，多行动。因为困难是给有潜力的人准备的奠基石，整合人心、凝聚人心付诸行动是最重要的工作。</p>
<p>&middot;高管B错了，您能够这么着？只能挨罚挨骂。(2008-07-23)&nbsp;&nbsp; [作 者] xieshiling&nbsp; [公 司] 济南科技有限公司 <br />1、<span style="color: #0000ff;">从背景看，前项目经理是高人，项目进展到这种程度还能够高升，个人有背景或者有特长，能够一俊遮百丑。<br /></span>2、接任的项目经理A，没有办法，只能先挨骂再说，否则，还会被前项目经理穿上小鞋。如果现在的项目经理按照前面很多的分析说的，了解现状，整理信息，呈报上级去认识该项目的真相，估计会引起很多后患，会存在给人印象不好，除非你能够做得更好。<br />3、项目经理A错了，错在机会不好。<br />4、项目经理A还是做了很多工作的，比如追加了资源来处理，结果还没有处理好，问题就是项目经理A是该挨骂了，估计经验是不足的。下一步如何做，只能是多吃亏，多挨骂，才能够解决这个问题。</p>
<p>&middot;如何做好替罪羊(2008-07-14)&nbsp;&nbsp; [作 者] aaron&nbsp; [公 司] 公司 <br />背景分析：前任项目经理带领的项目，领导B的看法是：此项目一切顺利，只要改动一下程序，完成最后一阶段测试就大功告成了。而事实是：原PM没留下任何文档记录。已完成的工作也没有文档固化下来。<br />这说明前任项目经理有背景的可能性最大，公司管理也混乱，一个项目竟然没有任何文档，或者有文档也不移交。<br />同事A接管项目后的工作个人认为从这些方面进行：<br /><span style="color: #0000ff;">1、如同事A原来不是在此项目，他可以先通项目组成员逐个沟通，了解项目的现状；同领导B沟通获取一些能获取的项目资料；同客户沟通了解项目的整体情况；</span><br />2、项目组成员按原安排工作；<br />3、写一份项目现状分析报告提交领导B；<br />4、同客户沟通，根据目前项目形成一份工作计划；<br />5、获得许可后，按新计划执行。</p>
<p>&middot;职场公交车(2008-07-01)&nbsp;&nbsp; [作 者] 沃双喜&nbsp; [公 司] 西屋 <br />新的项目经理A在中途好不容易坐上座位，可惜还没坐热就到终点站要下车了。这是职场的规则，只可惜没能早坐上座位，所以运气不佳。<br />领导B看来很自信，但是他对项目的理解，管理和监控远远不够。否则，不会什么文档和记录都没有的。遇到这样的领导和这样的时机，的确很有挑战性。<br />如果我是A，当我接手时，如果没留任何资料，唯一的办法就是找项目组员了解项目进度，以及里程碑。都有什么输出，尽可能的找，也要和客户侧面了解，最后列个清单和领导B用事实谈。<br />其实我也是新手，从质量转到项目不久，也只能从方法上谈。还请各位多给指点</p>
<p>&middot;借鉴(2008-05-28)&nbsp;&nbsp; [作 者] 黄赟&nbsp; [公 司] 赣州城建市政工程管理有限公司 <br />我认为A接受后应该做以下几件事<br />1、对该项目做全方位的详细报告。<br />2、对该项目需完成仍存在哪些问题。<br />3、针对这些问题需如何去处理。<br />4、可能存在的风险，如何规避或降低。</p>
<p>&nbsp;&middot;从行政上来看(2008-04-21)&nbsp;&nbsp; [作 者] 李敏策&nbsp; [公 司] 杭州天夏&nbsp; <br />从行政角度来看，领导B不可能迟钝到这种程度；除非前经理从来没有如实汇报过工作，这就说明了一个问题：前经理是领导B的心腹或者是领导B的领导的心腹，反正就是B要么管不了前经理的，要么就很信任前经理的。<br /><span style="color: #0000ff;">从作者描述来看，这个项目绝对是没有前途的，因此的出的结论是：此次临阵换将是为了保全前经理，A根本就是一个替罪羊。<br /></span>A最好的方式就是列出需要得到的信息及必须领导签字确认得到了多少信息（没得到也行，但必须让B确认该项信息没有得到）；然后再与各方沟通，努力做好范围控制和进度控制，有问题及时上报B，不要不好意思，因为没有了后顾之忧，做起来反而能放开手脚，说不定真能把烂项目做好。<br />最后，如果每做好，反正前面已有铺垫，也怪不到你头上；做好了，说明你很有能力，换个环境吧，这样的领导不适合你。</p>
<p>&middot;人在职场，要注意保护自己(2008-01-22)&nbsp;&nbsp; [作 者] 周预&nbsp; [公 司] 湘潭&nbsp; <br />首先提出以下观点：<br /><span style="color: #0000ff;">1、临阵换将，大忌！对于项目组成员而言，需要适应一个新领导的行为风格，对于项目经理，又有一个熟悉项目环境的过程，无疑增加了项目的风险，尤其在一个制度比不完善的企业内。但企业战略需要如此，只好将就了。<br />2、企业的项目管理制度方面存在严重缺陷，作为一个软件企业，文档管理、范围管理、质量控制、配置管理、合同管理等制度基本上没有或者流于形式，项目成败完全依赖于项目经理和成员的个人能力，难有制度保证。<br />3、企业人力资源管理和绩效管理体系存在问题，提升一个问题重重的项目领导，又何以服众，又何以满足企业的战略目标，明升暗降还可！</span></p>
<p>项目经理错了，错在以下几个方面：<br />1、工作交接过于轻率或经验不足。项目的移交必须由双方签字和双方的主管领导签字，移交了哪些资料应书面记录已备将来分析责任之用。在本项目中，A明显经验不足，连起码的文档都没有就接手，挨批也不能怨天尤人了，吃一堑长一智吧。当然信息不对称也是一个原因之一。<br />2、不敢说&ldquo;不&rdquo;。对于这个项目而言，如果A在接手手续时，就知道项目资料不全，并预知项目风险过大时，就要敢于说出自己的想法，要求前任提交必须的资料，切不可以以为领导提拔了自己，不好意思也把不敢也罢说出自己的想法，尤其是前任项目经理将提拔为自己的上级时更是为难。这样往往吃亏在自己，卖了力还不讨好，要敢于表达自己的不同意见，毕竟先小人后君子嘛！至少比勉强接受，后又挨批哑巴吃黄连强，要学会保护自己！<br />3、项目管理经验不足。在发现项目文档欠缺时，A接手一个项目应先会同客户和本公司的商务及前任项目经理确认项目目标和范围，达成共识，并文档化形成项目工作基础。</p>
<p>建议：A应该这么做:<br />1、做好交接工作，移交清单应双方签字认可，可能的话应请双方主管确认，对于交接中发现的问题应及时沟通，告知领导，切不可碍于面子，中国古话说得好，先小人后君子。<br />2、认清形势，由于信息不对称，A不可能一下子发现项目的问题，应尽快熟悉项目，可以采取与项目组成员、客户、商务等沟通，听取他们的建议意见看法，然后作出正确判断：<br />a）同项目组成员沟通，项目组成员熟悉项目工作尤其是本职工作，争取他们的支持并达成一致意见，听听他们的坦诚的建议和意见，有点困难，需要一定的沟通技巧。<br />b）同客户沟通，理解他们的需求和期望。<br />c）查阅整理资料，包括商务合同等，确保对项目状况形成一个清晰的判断。<br />d）及时向领导沟通，报告项目状况，确保领导对项目有个清晰的判断，让领导认识问题的严峻性。当然这样做容易造成人际关系紧张，需要权衡利弊和沟通技巧。<br />3、接手一个项目应先会同客户和本公司的商务及前任项目经理确认项目目标和范围，达成共识，并文档化形成项目工作基础。<br />4、以项目目标和范围说明书为基础，进行项目绩效评估，重新进行项目计划调整，并争取公司支持最佳必须的资源，争取客户理解和谅解，达到一致认识，并作为前一段时间工作的基线记录下来。<br />&nbsp;<br />&middot;A的失误与启发(2008-01-16)&nbsp;&nbsp; [作 者] 李永新&nbsp; [公 司] SAP company&nbsp; <br />A做为半路接手的项目经理，A范了以下几点错误：<br />1、A接手项目时没有与前项目经理进行充分的沟通，没有整理遗留问题，导致对项目一知半解的.<br />2、A接手项目后没有与客户进行有效的沟通，没能控制项目的范围、及时控制客户的需求，导致客户需求不断增加，增加了项目的难度.<br />3、A接手项目后没能制定合理与有效的计划. 计划是有效实施的工具，具体明细的计划能够很好的控制项目实施的进度. 如果A提前把项目风险分析与计划安排提早告诉B，也就不会事后受到B的批评了.</p>
<p>对于半路接手的项目经理，我觉得应该这样处理：<br />1、交接的时候把前任项目经理手上的资料或者是告诉你的内容尽量的记录和保留。（如果不完整也没有关系，因为有可能他自己很多东西也没有记录或者保留）<br />2、项目交接后，召开项目小组成员碰头会，将项目的所有第一手资料进行整理（比如项目目前最新状态等信息）<br />3、会后，将以上的资料进行整理和分析，如果还有什么不清楚的地方，再找人单独谈，或者与以前的项目经理联系。<br />4、对于整理好后的项目，需要重新拟订时间节点，对项目的最基本的资料再次发给项目小组进行统一。当然时间节点要提交给领导以及客户的项目经理进行知悉。<br />5、接下来就是以前的一些非关键文件的补充和查找，这个可以自己补充也可以多方面搜集。对于客户需要回签的文件，必要时找客户对应的联系人进行沟通索要。</p><img src="http://www.cnblogs.com/kevinxiong/aggbug/1680761.html?type=1" width="1" height="1" alt=""/><p>评论: 4　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· QQ一亿在线背后的摩尔速度<span style="color:gray">(2010-03-08 17:29)</span><br/>· 美科技博客揭秘社交网站Facebook创建过程<span style="color:gray">(2010-03-08 17:21)</span><br/>· 各大网站纷纷推出妇女节专题<span style="color:gray">(2010-03-08 17:14)</span><br/>· 首款iPad游戏《Zen Bound释禅2》截图曝光<span style="color:gray">(2010-03-08 17:09)</span><br/>· 《星际争霸2》韩国遭拒 暴雪转战网吧推广<span style="color:gray">(2010-03-08 17:00)</span><br/></p><p>编辑推荐：2010年3月编程语言排行榜<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47273</link>
<title><![CDATA[使用优盘安装Win7]]></title>
<author>sunny段段</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 13:56:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47273</guid>
<description><![CDATA[ <p>阅读: 845 评论: 8 作者: sunny段段 发表于 2010-03-08 13:56 原文链接</p><p class="MsoNormal"><span style="font-family:宋体">该方法可以帮助有</span><span lang="EN-US">ISO</span><span style="font-family:宋体">却没有光盘或没光驱的同志用优盘来安装</span><span lang="EN-US">win7</span><span style="font-family:宋体">。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="text-indent:21.0pt"><span style="font-family:宋体">前提：</span></p>

<p class="MsoListParagraph" style="margin-left:39.0pt;text-indent:-18.0pt;
mso-list:l2 level1 lfo1"><span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"><span style="mso-list:Ignore">1．<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp; </span></span></span><span style="font-family:宋体">有</span><span lang="EN-US">win7</span><span style="font-family:宋体">安装</span><span lang="EN-US">ISO</span><span style="font-family:宋体">，或全部安装文件。</span></p>

<p class="MsoListParagraph" style="margin-left:39.0pt;text-indent:-18.0pt;
mso-list:l2 level1 lfo1"><span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"><span style="mso-list:Ignore">2．<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp; </span></span></span><span style="font-family:宋体">有</span><span lang="EN-US">4G</span><span style="font-family:宋体">或以上容量优盘。</span></p>

<p class="MsoListParagraph" style="margin-left:39.0pt;text-indent:-18.0pt;
mso-list:l2 level1 lfo1"><span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"><span style="mso-list:Ignore">3．<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp; </span></span></span><span style="font-family:宋体">电脑支持</span><span lang="EN-US">USB</span><span style="font-family:宋体">启动方式。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="margin-left:21.0pt"><span style="font-family:宋体">制作过程：</span></p>

<p class="MsoListParagraph" style="margin-left:39.0pt;text-indent:-18.0pt;
mso-list:l1 level1 lfo2"><span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"><span style="mso-list:Ignore">1．<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp; </span></span></span><span style="font-family:宋体">快速格式化优盘。（注意备份优盘数据，避免杯具）</span></p>

<p class="MsoListParagraph" style="margin-left:39.0pt;text-indent:-18.0pt;
mso-list:l1 level1 lfo2"><span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"><span style="mso-list:Ignore">2．<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp; </span></span></span><span style="font-family:宋体">使用虚拟光驱加载</span><span lang="EN-US">win7</span><span style="font-family:宋体">光盘镜像。</span></p>

<p class="MsoListParagraph" style="margin-left:39.0pt;text-indent:-18.0pt;
mso-list:l1 level1 lfo2"><span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"><span style="mso-list:Ignore">3．<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp; </span></span></span><span style="font-family:宋体">打开命令行，路径切换至虚拟光驱的</span><span lang="EN-US">boot</span><span style="font-family:宋体">目录下。</span></p>

<p class="MsoListParagraph" style="margin-left:39.0pt;text-indent:-18.0pt;
mso-list:l1 level1 lfo2"><span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"><span style="mso-list:Ignore">4．<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp; </span></span></span><span style="font-family:宋体">运行命令</span><strong><em><span lang="EN-US"> bootsect /nt60 G: </span></em></strong><span lang="EN-US">&nbsp;&nbsp;</span><span style="font-family:宋体">（</span><span lang="EN-US">G:</span><span style="font-family:宋体">是优盘的盘符）</span></p>

<p class="MsoListParagraph" style="margin-left:39.0pt;text-indent:-18.0pt;
mso-list:l1 level1 lfo2"><span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"><span style="mso-list:Ignore">5．<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp; </span></span></span><span style="font-family:宋体">拷贝</span><span lang="EN-US">win7</span><span style="font-family:宋体">镜像内所有文件到优盘。</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<p class="MsoNormal" style="margin-left:21.0pt"><span style="font-family:宋体">安装过程：</span></p>

<p class="MsoListParagraph" style="margin-left:39.0pt;text-indent:-18.0pt;
mso-list:l0 level1 lfo3"><span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"><span style="mso-list:Ignore">1．<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp; </span></span></span><span lang="EN-US">ThinkPad </span><span style="font-family:宋体">在启动时按</span><span lang="EN-US">F12</span><span style="font-family:宋体">可直接选择引导方式，选择</span><span lang="EN-US">USB</span><span style="font-family:宋体">启动</span></p>

<p class="MsoListParagraph" style="margin-left:39.0pt;text-indent:-18.0pt;
mso-list:l0 level1 lfo3"><span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"><span style="mso-list:Ignore">2．<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp; </span></span></span><span style="font-family:宋体">其他类型电脑，需要进入</span><span lang="EN-US">BIOS</span><span style="font-family:宋体">设置优盘启动。</span></p>

<p class="MsoListParagraph" style="margin-left:39.0pt;text-indent:-18.0pt;
mso-list:l0 level1 lfo3"><span lang="EN-US" style="mso-fareast-font-family:Calibri;mso-bidi-font-family:Calibri"><span style="mso-list:Ignore">3．<span style="font:7.0pt &quot;Times New Roman&quot;">&nbsp; </span></span></span><span style="font-family:宋体">设置好优盘启动，引导优盘，进入正常安装。之后步骤与光盘安装相同。</span></p><img src="http://www.cnblogs.com/sunnycoder/aggbug/1680750.html?type=1" width="1" height="1" alt=""/><p>评论: 8　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· QQ一亿在线背后的摩尔速度<span style="color:gray">(2010-03-08 17:29)</span><br/>· 美科技博客揭秘社交网站Facebook创建过程<span style="color:gray">(2010-03-08 17:21)</span><br/>· 各大网站纷纷推出妇女节专题<span style="color:gray">(2010-03-08 17:14)</span><br/>· 首款iPad游戏《Zen Bound释禅2》截图曝光<span style="color:gray">(2010-03-08 17:09)</span><br/>· 《星际争霸2》韩国遭拒 暴雪转战网吧推广<span style="color:gray">(2010-03-08 17:00)</span><br/></p><p>编辑推荐：2010年3月编程语言排行榜<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47274</link>
<title><![CDATA[20个创意汉堡包]]></title>
<author>yleo</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 10:48:50</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47274</guid>
<description><![CDATA[ <p><img border=0 src="http://img.diglog.com/img/2010/3/middle_33484ff27c594c289d742aa59256ba1d.jpg" /></p><br/>看到这些好看又好吃的汉堡包，是否胃口大开呢？<br/><br/>原始链接:http://hi.baidu.com/yleo550/blog/item/a3dec39691f99615d31b704e.html<br/>diglog链接:http://www.diglog.com/story/life_food_331918.html  ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47267</link>
<title><![CDATA[Silverlight 资源的使用]]></title>
<author>ghj1976</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 10:24:21</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47267</guid>
<description><![CDATA[ <p>我们在Silverlight 项目中，新加一个文件，比如一个图片文件，这个文件的属性会有下面2个选项，这两个选项决定了这个图片资源如何存储，如何使用。</p>  <p>先说简单的，资源文件的 Copy to OutPut Directory 属性， 这个属性有如下三个选项：</p>  <p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog.joycode.com/images/metaapis/64/WindowsLiveWriter/Silverlight_8981/image_thumb_1.png" width="447" height="231" /> </p>  <p>他们都是在程序编译或者部署时，判断此资源文件是否要同步用的。</p>  <table border="2" cellspacing="0" cellpadding="2" width="409"><tbody>     <tr>       <td valign="top" width="158">Do not copy</td>        <td valign="top" width="247">不做数据同步</td>     </tr>      <tr>       <td valign="top" width="158">Copy always</td>        <td valign="top" width="247">每次都会被同步过去</td>     </tr>      <tr>       <td valign="top" width="158">Copy if newer</td>        <td valign="top" width="247">当有新版本存在时，才会被同步过去</td>     </tr>   </tbody></table>  <p>&#160;</p>  <p>Build Action 属性则复杂多了， 下面是VS2010中， Silverlight 4 项目资源文件的Build Action 属性截图。</p>  <p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog.joycode.com/images/metaapis/64/WindowsLiveWriter/Silverlight_8981/image_thumb.png" width="393" height="372" /> </p>  <p>注意，上面罗列了一些不适合资源文件的 Build Action 属性，在使用资源文件时，可以忽略这些。</p>  <p></p>  <p>&#160;</p>  <table border="2" cellspacing="0" cellpadding="2" width="711"><tbody>     <tr>       <td valign="top" width="208">None</td>        <td valign="top" width="499">资源既不会被集成到程序集内，也不会打包到xap包中。不过我们可以通过设置CopyToOutputDirectory选项让其自动拷贝到xap包所在目录。          <br />这种情况下, 访问这个图片的相对Uri需要以&quot;/&quot;开始。           <br />          <p>适用场景：</p>          <p>在大多数情况下，我们希望把video/audio文件放到xap的外面，因为这种文件一般都比较大，会影响silverlight应用的加载，而且一般的视频音频文件都是压缩格式的，放到xap中也不会起到减少他们文件大小的作用。            <br />类似图片视频这种资源文件生成操作为None时和他们没有被添加到项目里是一样的，都可以用绝对Uri进行引用。</p>       </td>     </tr>      <tr>       <td valign="top" width="208">Compile</td>        <td valign="top" width="499">不适合用于资源文件。          <br />类文件要用&quot;Compile&quot;生成操作， 就是指项目里.cs或.vb文件。</td>     </tr>      <tr>       <td valign="top" width="208">Content</td>        <td valign="top" width="499">资源会被打包在Xap包里面。          <br />这种情况下, 访问这个图片的相对Uri需要以&quot;/&quot;开始。           <br />在这种方式下，如果没有在xap中找到图片文件，那么silverlight会自动从当前xap应用所在的文件夹下来找所需图片文件，           <br />如果还没有找到那么就触发ImageFailed事件，           <br />这种方式比较适合在多个程序集引用相同文件时采用。</td>     </tr>      <tr>       <td valign="top" width="208">Embedded Resource</td>        <td valign="top" width="499">         <p>这种方式会把文件嵌入到程序集中，silverlight无法通过Uri引用在xaml和c#里对这个文件进行使用，微软不建议在silverlight采用这种方式在程序集里嵌入资源。            <br />如果有这种需求可以用             <br />Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(string path)相关的方法得到文件的stream引用。</p>       </td>     </tr>      <tr>       <td valign="top" width="208">ApplicationDefinition</td>        <td valign="top" width="499">         <p>silverlight程序的入口xaml文件(默认就是App.xaml)应该设置为这个&quot;应用定义&quot;。其他文件都不适合用这个。</p>       </td>     </tr>      <tr>       <td valign="top" width="208">Page</td>        <td valign="top" width="499">不适合用于资源文件。          <br />所有的用户控件， 页面和子窗体(usercontrol/page/childwindow)的xaml文件应该采用的生成操作。           <br />如果改为别的方式那么会导致后台对应的代码文件无法链接到这个xaml文件。 采用&quot;Page&quot; build action时xaml里的错误会导致工程无法正确生成。</td>     </tr>      <tr>       <td valign="top" width="208">CodeAnalysisDictionary</td>        <td valign="top" width="499">代码分析使用，Silverlight中可以忽略</td>     </tr>      <tr>       <td valign="top" width="208">Resource</td>        <td valign="top" width="499">资源会被打包在程序集内部。          <br />选择这种生成方式后,该资源文件会被嵌入到该应用的程序集中，就是说打开生成的xap是看不到这个文件的。           <br />          <p>可以用相对于当前的XAML文件的相对Uri访问，            <br />如&lt;Image Source=&quot;silverlight.png&quot; /&gt;             <br />或是&lt;Image Source=&quot;./silverlight.png&quot; /&gt;，</p>          <p>在子文件夹里的可以用            <br />&lt;Image Source=”./images/sl.jpg” /&gt;访问到。</p>          <p>最保险的方式是采用特有的程序集资源URI访问,格式为            <br />&lt;Image Source=&quot;/{assemblyShortName};component/Foo.jpg&quot;/&gt;，</p>          <p>这种方式还可以引用到xap中的其他程序集中的图片。</p>          <p>这种生成方式的系统资源可以直接用Application.GetResourceStream(uri).Stream在代码里来得到。</p>       </td>     </tr>      <tr>       <td valign="top" width="208">SplashScreen</td>        <td valign="top" width="499">         <p>&quot;SplashScreen&quot;是这个选项是WPF的启动画面使用的。&#160; silverlight启动加载画面是用的其他方式实现的， 所以在silverlight里不要用这个方式。 </p>       </td>     </tr>      <tr>       <td valign="top" width="208">EntityDeploy</td>        <td valign="top" width="499">这个是EntityFramework采用的生成方式， 在silverlight里是没用。</td>     </tr>   </tbody></table>  <p>&#160;</p>  <p><strong>参考资料：</strong></p>  <p>分析silverlight里的URI引用资源文件的各种情况    <br />http://bbs.blueidea.com/viewthread.php?tid=2941697</p>  <p>Silverlight图片相对路径的设置    <br />http://www.cnblogs.com/yangfan/archive/2009/12/14/1623647.html</p>  <p>关于Silverlight资源文件(如:图片)的放置位置及其引用(相对路径）    <br />http://www.cnblogs.com/star250/archive/2009/10/15/1583665.html</p>  <p>Silverlight资源文件    <br />http://msdn.microsoft.com/zh-cn/library/cc296240(VS.95).aspx</p>  <p>图片等资源的引用路径问题    <br />http://www.cnblogs.com/kevinyang/archive/2008/11/16/1334712.html</p><br/><hr/>博客堂源代码发布已经发布于Codeplex，邀请您来捉臭虫<img src="http://blog.joycode.com/ajaxhelper.aggbug?PostId=115901&BlogId=64" > ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47268</link>
<title><![CDATA[我眼中的VS2010]]></title>
<author>ghj1976</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 9:21:03</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47268</guid>
<description><![CDATA[ <p> VS2010正式版马上就要发布了，从09年国庆节后开始使用VS2010 Beta2测试版，到现在也已4个月了，VS2010的的变化很大，但是给我带来比较大影响的反而是几个小的功能变革。</p>  <p><strong>VS2010改变了我对WPF观念</strong></p>  <p> 在听说VS2010是WPF开发之前，我总觉得WPF由于要实现这么多绚丽的界面，在性能上肯定损耗的不少。在之前，由于对美好界面的渴望，我也自己学习过WPF，由于公司日常工作用不到WPF，也就是写写小程序玩玩，但是能用WPF来开发VS2010，在此之前我是无论如何都没有想到的，非常吃惊，这就是我当初听到VS2010要用WPF来开发的感受。在使用VS2010这么久后，VS2010测试版虽然有时候会时不时没有响应，但是它的速度，性能，一点都不比我装在同一台机子上的VS2008差。VS2010 RC 版据说解决了那些没有响应的问题，同时速度优化了很多，由于我要用到Silverlight 4 的开发，就没装 VS2010 RC 版，VS2010的正式版确实很值得期待。网上说 VS2010 RC 版对性能的改进体验非常深刻，参看：.NET 4 RC版 发布了 这篇博客。</p>  <p><strong>代码智能提示的改进</strong></p>  <p> .NET Framework 的函数库越来越强大，也越来越多，不是特长常用的，函数名确实难以记住，VS2008 开发环境的智能提示是根据方法或者属性的起始字母来选择的，如下图所示：</p>  <p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog.joycode.com/images/metaapis/64/WindowsLiveWriter/VS2010_E76A/image_thumb_2.png" width="668" height="284" /> </p>  <p> VS2010中则搜索的是包含搜索词的所有函数和属性。这样如下图所示，我们搜索 edit ，不仅仅可以搜索出 EditIndex，还可以搜索出字母中间带Edit的方法，属性，事件。 </p>  <p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://blog.joycode.com/images/metaapis/64/WindowsLiveWriter/VS2010_E76A/image_thumb_1.png" width="685" height="226" /> </p>  <p>这样，那些我们没有精确记忆的属性和方法就会出现在智能提示中，对我们的编程非常方便实用。</p>  <p>有关这方面的内容你可以参看： VS 2010 和 .NET 4.0 系列之《VS 2010代码智能提示的改进》篇</p>  <p>&#160;</p>  <p><strong>导航和查询代码的改进</strong></p>  <p> 当我们阅读一个代码非常膨大，而不是又不是特别熟悉它的代码结构时，如何找到并定位代码，会是一个难题。这个功能VS2010新增的功能对我们非常有用。如下图：(Ctrl+逗号)的键盘快捷键就可以打开下面的“Navigate To（导航到）”对话框。在Search terms 中我们输入2个关键字：“cache action”，就可以搜索出包含这两个关键字的方法，类，属性，事件。这跟上面的智能提示一样，是包含，而不是以某个字开头。</p>  <p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image_thumb_7E22DE68" border="0" alt="image_thumb_7E22DE68" src="http://blog.joycode.com/images/metaapis/64/WindowsLiveWriter/VS2010_E76A/image_thumb_7E22DE68_thumb.png" width="657" height="363" /> </p>  <p>有关这方面的内容你可以参看： VS 2010 和 .NET 4.0 系列之《在VS 2010中查询和导航代码》篇</p>  <p>&#160;</p>  <p><strong>鼠标滚轮滚动，对应字体大小的变化</strong></p>  <p> 这个功能对演示代码非常有帮助，比如公司内部，我在给大家演示一些代码时，由于现在的屏幕分辨率越来越大，我又习惯用最大的分辨率，这样稍稍离我远点的，就看不清楚编辑器的内容，以前我是在演示时，修改VS开发环境编辑器的默认字体大小，不演示了，再改回去，现在我不需要反复的改来改去，直接用鼠标中键滚轮来回滚动，就可以轻松实现字体的放大和缩小，非常实用，非常方便，我经常使用它。</p>  <p> 使编程更容易；让我们对WPF更有信心。这就是我对VS2010的感觉。</p><br/><hr/>博客堂源代码发布已经发布于Codeplex，邀请您来捉臭虫<img src="http://blog.joycode.com/ajaxhelper.aggbug?PostId=115900&BlogId=64" > ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47258</link>
<title><![CDATA[时间管理&mdash;&mdash;珍惜时间碎片]]></title>
<author>Autumoon</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 7:00:00</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47258</guid>
<description><![CDATA[ <p>阅读: 8 评论: 0 作者: Autumoon 发表于 2010-03-08 07:00 原文链接</p><p><font color="#808080" size="2">【固定链接：</font><font color="#808080" size="2">http://www.autumoon.com/post/2010/01/29/TreasureTimeShard.aspx</font><font color="#808080" size="2">】</font></p>  <p><font size="2"><img style="border-right-width: 0px; margin: 0px 10px 5px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="面包总是会有碎屑的。" border="0" alt="面包总是会有碎屑的。" align="left" src="http://images.cnblogs.com/cnblogs_com/Autumoon/WindowsLiveWriter/c93d6dca6001_8841/Bread_3.jpg" width="200" height="150" /> 吃面包或者饼干一类的东西的时候，常常会掉落一些细小的碎屑，或许大多数朋友都不会太在意，因为如果要捡起来吃掉，一是觉得不卫生，二是似乎太小没有那个必要，节约也不至于到这种程度吧。假设一个天天以面包为食的洋人，他每次吃面包都不可避免地会掉落一些面包屑，虽然集到一起大概也就不起眼的一小撮，但是一个月下来，面包屑大概就不是一小撮了，一年下来，或许掉落的面包屑都跟一个面包差不多大了。</font></p>  <p><font size="2">那么，一年里我浪费掉的时间碎片加起来有多少呢？一个小时？一天？一个月？不敢试问大家，所以只好扪心自问一下。一天浪费2个小时似乎不是一件很难的事情，可是一年下来，别吃惊，这意味着浪费了整整一个月！很可怕，不是么？一个月的时间（而且每天是按24小时而不是8小时计算）可以做多少事情啊！这一个月里，世事风云变化，有多少机会和跟咱擦肩而过呢？</font></p>  <p><font size="2">那么什么是我提到的“时间碎片”呢？虽然我们每一天里都会有两大块时间分别在处理工作和生活上的事情，在这两大块时间里又可以进一步分出几大块时间来处理不同的事务：会见客户1小时，制定明年发展规划2小时，和同事一起排练年会节目40分钟等等。就好比吃面包的时候先把面包掰成两半，然后再分别几口吃掉一样。可是，在一项事务跟下一项事务之间，总是会产生一些时间碎片，比如早上去公司上班，地铁上耗费30分钟（意味着一天在路上就得耗费1个小时）；晚上安排花1个小时跟好朋友一起吃饭，可是等他来就花了20分钟；安排30分钟去理发，排队又花了10分钟等等。这些时间碎片分开来看虽然都不太起眼，但是加起来，一天凑够2个小时我觉得问题不大。这样算下来，一年里的时间碎片加起来要说有1个月我觉得也没啥夸张的了。</font></p>  <p><font size="2">我们就拿等待来说吧。在餐厅里等朋友来是一件很空虚无聊的事情，因为这个时候既没有人陪您聊天，也不能开始品尝美味佳肴。人一旦空虚，对时间的感知就特别敏感，也就容易觉得时间过得很慢；相反，忙碌的人对时间的感知会相对比较迟钝，也就容易觉得时间过得很快了。如果不想等待的过程变成一种煎熬，那么就应该想办法让自己对时间的感知变得迟钝一些，也就是找点儿事情来做。在餐厅能做什么呢？显然不能到后厨去帮老板娘洗碗。那就叠餐巾纸吧，叠一千只千纸鹤我就不信他还在路上堵着呢。好吧，我承认我出的都是些馊主意。事实上，有很多有意义的事情可以充分利用这样的时间来进行。您可以拿出最近正计划要阅读的书籍来读一读，10分钟时间大概可以阅读2-5页（如果是连环画就快得多了），超常发挥的话可能更多，而根据我的经验，在餐厅、地铁这样吵杂的环境里读书，虽然感觉不好但更有效果，因为更加意识到要专注，而环境太安逸往往却容易走神。或者您觉得随身带一本书是一件很麻烦的事情，手机您总该有一个吧，不管是智能手机还是普通手机，都会有阅读文本文件的功能，从网上找一本您感兴趣但又不着急看完的电子书存在手机里，这个时候就可以拿出来看一看。或者您追求更洒脱，觉得随身带手机也很麻烦，那么何不在脑子盘算一下最近要处理的比较重要的事情呢，比如今天写的程序里可能存在哪些逻辑错误、明年我想买房的话今年至少要完成哪些事情呢，等等。</font></p>  <p><font size="2"><img style="border-right-width: 0px; margin: 0px 0px 5px 10px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="" border="0" alt="" align="right" src="http://images.cnblogs.com/cnblogs_com/Autumoon/WindowsLiveWriter/c93d6dca6001_8841/Race_3.jpg" width="200" height="125" /> 有人说任何事情只要您迈出第一步，就等于完成了一半。我觉得有道理。起步很重要，克服掉我们的恐惧感和懒惰心态，但接下来的坚持也非常重要。假如每次等待的时候，都会下意识地掏出手机来阅读电子书，我相信您会感觉同样长的一段时间，您比过去充了更多的电。</font></p>  <p><font size="2">充分利用时间碎片的前提是咱们意识到时间碎片是值得珍惜的。我们的生活和工作环境里，不乏各种各样的牛人，如果您有一颗上进的心，那么很多时候咱们会选择接近这些牛人，学习他们的长处，了解他们的优势，并且在心里默默地将他们作为自己需要超越的对象。或许我们可以把他们看做是我们人生道路上的一个个会移动的里程碑，我们在不断进步的同时他们也在进步，因此，如果我们想要赶上甚至超越他们的话，就必须给自己提供更多的能量，这些能量从哪里来，就是从时间碎片里得来的。</font></p>  <p><font size="2">经常会听到类似这样的话：“我不是天才，我只是在别人睡觉的时候还在学习而已。”当然不是说为了进步咱就不睡觉了，睡眠相当重要，而且也不一定非要和别人比，咱们来进一步地考虑这句话。假设以往在等人的时候，我通常的做法是发呆，那么现在我提醒自己不要发呆了，而是好好地利用这点儿时间多学点儿知识，比如看点儿文集、传记之类的不需要理论研究的书籍，从那些牛人们的思维中发掘自己需要的给养。只要功夫深，铁杵磨成针，即使一时半会儿咱还不能赶上那些牛人们的水平和地位，但只要在不断进度，咱就会更有信心，这份信心即使不是为了去超越别人，也会觉得自己可以做到问心无愧，因为自己没有浪费光阴。</font></p>  <p><font size="2">机会都是留给有准备的人。但是它又不会在到来前提前通知咱一下：“您准备一下吧，我要来了。”它会来得很突然，如果您没有准备，它就会很淡定地飘过，即使您的眼神再怎么恋恋不舍都无济于事；但是如果您有所准备，那么就可以很迅速很准确地捕获它。所以我建议咱们每天早上醒来后第一件事就是问自己，假设今天有个什么样的机会，我准备好了吗？</font></p>  <p><font size="2">所以，要不断地明确自己的目标和理想，才会意识到时间碎片是值得珍惜的。只有真正地意识到自己的生活中存在很多可以利用的时间碎片，才会耻于将“最近太忙，没时间”这样的口头禅挂在嘴边。所以，充分地利用自己的时间，每天都要求自己进步一点点，时间长了，量变终将会发生质变！</font></p><img src="http://www.cnblogs.com/Autumoon/aggbug/1680508.html?type=1" width="1" height="1" alt=""/><p>评论: 0　查看评论　发表评论</p><p>找优秀程序员，就在博客园</p><hr/><p>最新新闻：<br/>· 微软:2010年Windows 7计划销量3亿套<span style="color:gray">(2010-03-07 21:04)</span><br/>· IE6葬礼看个清楚，现场照片<span style="color:gray">(2010-03-07 21:03)</span><br/>· 思科周二将公布超高速互联网接入系统<span style="color:gray">(2010-03-07 20:52)</span><br/>· 富士通前总裁要求复职 称此前辞职是被逼<span style="color:gray">(2010-03-07 20:51)</span><br/>· 浙江资本移情网游产业<span style="color:gray">(2010-03-07 20:39)</span><br/></p><p>编辑推荐：Adobe、微软论剑Flash、Silverlight与HTML5<br/></p><p>网站导航：博客园首页&nbsp;&nbsp;个人主页&nbsp;&nbsp;新闻&nbsp;&nbsp;闪存&nbsp;&nbsp;小组&nbsp;&nbsp;博问&nbsp;&nbsp;社区&nbsp;&nbsp;知识库</p> ]]></description>
</item>
<item>
<link>http://h31home.com/rss/blogto.asp?ID=47275</link>
<title><![CDATA[只要有心，爱无处不在]]></title>
<author>youhuang</author>
<category><![CDATA[]]></category>
<pubDate>2010-3-8 1:23:36</pubDate>
<guid>http://h31home.com/rss/blogto.asp?ID=47275</guid>
<description><![CDATA[ <p><img border=0 src="http://img.diglog.com/img/2010/3/middle_3fa01abeaafd45edbd1fd7285b6ec50a.jpg" /></p><br/>一组收集自网络的创意图片，告诉你只要有心，爱无处不在。<br/><br/>原始链接:http://www.unicornblog.cn/user1/unicornblog/23832.html<br/>diglog链接:http://www.diglog.com/story/culture_photograph_331902.html  ]]></description>
</item>


</channel>
</rss>
