﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-9who的程序博客,天道酬勤</title><link>http://www.cnblogs.com/9who/</link><description>寻梦的岁月从不言辛苦几多，不问收获多几...</description><language>zh-cn</language><lastBuildDate>Thu, 21 Aug 2008 17:24:10 GMT</lastBuildDate><pubDate>Thu, 21 Aug 2008 17:24:10 GMT</pubDate><ttl>60</ttl><item><title>ASP.NET26个常用性能优化方法</title><link>http://www.cnblogs.com/9who/archive/2008/08/19/1271585.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Tue, 19 Aug 2008 09:33:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/08/19/1271585.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1271585.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/08/19/1271585.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1271585.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1271585.html</trackback:ping><description><![CDATA[<ol>
    <li><strong>数据库访问性能优化</strong><br />
    　　<font color="#ff3300"><em>数据库的连接和关闭</em></font><br />
    　　访问数据库资源需要创建连接、打开连接和关闭连接几个操作。这些过程需要多次与数据库交换信息以通过身份验证，比较耗费服务器资源。 ASP.NET中提供了连接池(Connection Pool)改善打开和关闭数据库对性能的影响。系统将用户的数据库连接放在连接池中，需要时取出，关闭时收回连接，等待下一次的连接请求。连接池的大小是有限的，如果在连接池达到最大限度后仍要求创建连接，必然大大影响性能。因此，在建立数据库连接后只有在真正需要操作时才打开连接，使用完毕后马上关闭，从而尽量减少数据库连接打开的时间，避免出现超出连接限制的情况。<br />
    　　<font color="#ff3300"><em>使用存储过程</em><br />
    </font>　　存储过程是存储在服务器上的一组预编译的SQL语句，类似于DOS系统中的批处理文件。存储过程具有对数据库立即访问的功能，信息处理极为迅速。使用存储过程可以避免对命令的多次编译，在执行一次后其执行规划就驻留在高速缓存中，以后需要时只需直接调用缓存中的二进制代码即可。另外，存储过程在服务器端运行，独立于ASP.NET程序，便于修改，最重要的是它可以减少数据库操作语句在网络中的传输。<br />
    　　<font color="#ff3300"><em>优化查询语句</em><br />
    </font>　　ASP.NET中ADO连接消耗的资源相当大，SQL语句运行的时间越长，占用系统资源的时间也越长。因此，尽量使用优化过的SQL语句以减少执行时间。比如，不在查询语句中包含子查询语句，充分利用索引等。</li>
    <li><strong>字符串操作性能优化</strong><br />
    　　<em><font color="#ff3300">使用值类型的ToString方法</font></em><br />
    　　在连接字符串时，经常使用"+"号直接将数字添加到字符串中。这种方法虽然简单，也可以得到正确结果，但是由于涉及到不同的数据类型，数字需要通过装箱操作转化为引用类型才可以添加到字符串中。但是装箱操作对性能影响较大，因为在进行这类处理时，将在托管堆中分配一个新的对象，原有的值复制到新创建的对象中。使用值类型的ToString方法可以避免装箱操作，从而提高应用程序性能。<br />
    　　<em><font color="#ff3300">运用StringBuilder类</font></em><br />
    　　String类对象是不可改变的，对于String对象的重新赋值在本质上是重新创建了一个String对象并将新值赋予该对象，其方法 ToString对性能的提高并非很显著。在处理字符串时，最好使用StringBuilder类，其.NET 命名空间是System.Text。该类并非创建新的对象，而是通过Append，Remove，Insert等方法直接对字符串进行操作，通过 ToString方法返回操作结果。 　　其定义及操作语句如下所示：<br />
    <div class="quote">int num;<br />
    System.Text.StringBuilder str = new System.Text.StringBuilder(); //创建字符串<br />
    str.Append(num.ToString()); //添加数值num<br />
    Response.Write(str.ToString); //显示操作结果</div>
    </li>
    <li><strong>优化 Web 服务器计算机和特定应用程序的配置文件以符合您的特定需要</strong><br />
    　　默认情况下，ASP.NET 配置被设置成启用最广泛的功能并尽量适应最常见的方案。因此，应用程序开发人员可以根据应用程序所使用的功能，优化和更改其中的某些配置，以提高应用程序的性能。下面的列表是您应该考虑的一些选项。<br />
    　　<em><font color="#ff3300">仅对需要的应用程序启用身份验证</font></em>。<br />
    　　默认情况下，身份验证模式为 Windows，或集成 NTLM。大多数情况下，对于需要身份验证的应用程序，最好在 Machine.config 文件中禁用身份验证，并在 Web.config 文件中启用身份验证。根据适当的请求和响应编码设置来配置应用程序。ASP.NET 默认编码格式为 UTF-8。如果您的应用程序为严格的 ASCII，请配置应用程序使用 ASCII 以获得稍许的性能提高。<br />
    　　<em><font color="#ff3300">考虑对应用程序禁用 AutoEventWireup</font></em>。<br />
    　　在 Machine.config 文件中将 AutoEventWireup 属性设置为 false，意味着页面不将方法名与事件进行匹配和将两者挂钩(例如 Page_Load)。如果页面开发人员要使用这些事件，需要在基类中重写这些方法(例如，需要为页面加载事件重写 Page.OnLoad，而不是使用 Page_Load 方法)。如果禁用 AutoEventWireup，页面将通过将事件连接留给页面作者而不是自动执行它，获得稍许的性能提升。<br />
    　　<em><font color="#ff3300">从请求处理管线中移除不用的模块</font></em>。<br />
    　　默认情况下，服务器计算机的 Machine.config 文件中节点的所有功能均保留为激活。根据应用程序所使用的功能，您可以从请求管线中移除不用的模块以获得稍许的性能提升。检查每个模块及其功能，并按您的需要自定义它。例如，如果您在应用程序中不使用会话状态和输出缓存，则可以从列表中移除它们，以便请求在不执行其他有意义的处理时，不必执行每个模块的进入和离开代码。</li>
    <li><strong>一定要禁用调试模式</strong><br />
    　　在部署生产应用程序或进行任何性能测量之前，始终记住禁用调试模式。如果启用了调试模式，应用程序的性能可能受到非常大的影响。</li>
    <li><strong>对于广泛依赖外部资源的应用程序，请考虑在多处理器计算机上启用网络园艺</strong><br />
    　　ASP.NET 进程模型帮助启用多处理器计算机上的可缩放性，将工作分发给多个进程(每个CPU一个)，并且每个进程都将处理器关系设置为其 CPU。此技术称为网络园艺。如果应用程序使用较慢的数据库服务器或调用具有外部依赖项的 COM 对象(这里只是提及两种可能性)，则为您的应用程序启用网络园艺是有益的。但是，在决定启用网络园艺之前，您应该测试应用程序在网络园中的执行情况。</li>
    <li><strong>只要可能，就缓存数据和页输出</strong><br />
    　　ASP.NET 提供了一些简单的机制，它们会在不需要为每个页请求动态计算页输出或数据时缓存这些页输出或数据。另外，通过设计要进行缓存的页和数据请求(特别是在站点中预期将有较大通讯量的区域)，可以优化这些页的性能。与 .NET Framework 的任何 Web 窗体功能相比，适当地使用缓存可以更好的提高站点的性能，有时这种提高是超数量级的。使用 ASP.NET 缓存机制有两点需要注意。首先，不要缓存太多项。缓存每个项均有开销，特别是在内存使用方面。不要缓存容易重新计算和很少使用的项。其次，给缓存的项分配的有效期不要太短。很快到期的项会导致缓存中不必要的周转，并且经常导致更多的代码清除和垃圾回收工作。若关心此问题，请监视与 ASP.NET Applications 性能对象关联的 Cache Total Turnover Rate 性能计数器。高周转率可能说明存在问题，特别是当项在到期前被移除时。这也称作内存压力。</li>
    <li><strong>选择适合页面或应用程序的数据查看机制</strong><br />
    　　根据您选择在 Web 窗体页显示数据的方式，在便利和性能之间常常存在着重要的权衡。例如，DataGrid Web 服务器控件可能是一种显示数据的方便快捷的方法，但就性能而言它的开销常常是最大的。在某些简单的情况下，您通过生成适当的 HTML 自己呈现数据可能很有效，但是自定义和浏览器定向会很快抵销所获得的额外功效。Repeater Web 服务器控件是便利和性能的折衷。它高效、可自定义且可编程。</li>
    <li><strong>将 SqlDataReader 类用于快速只进数据游标</strong><br />
    　　SqlDataReader 类提供了一种读取从 SQL Server 数据库检索的只进数据流的方法。如果当创建 ASP.NET 应用程序时出现允许您使用它的情况，则 SqlDataReader 类提供比 DataSet 类更高的性能。情况之所以这样，是因为 SqlDataReader 使用 SQL Server 的本机网络数据传输格式从数据库连接直接读取数据。另外，SqlDataReader 类实现 IEnumerable 接口，该接口也允许您将数据绑定到服务器控件。有关更多信息，请参见 SqlDataReader 类。有关 ASP.NET 如何访问数据的信息，请参见通过 ASP.NET 访问数据。</li>
    <li><strong>将 SQL Server 存储过程用于数据访问</strong><br />
    　　在 .NET Framework 提供的所有数据访问方法中，基于 SQL Server 的数据访问是生成高性能、可缩放 Web 应用程序的推荐选择。使用托管 SQL Server 提供程序时，可通过使用编译的存储过程而不是特殊查询获得额外的性能提高。</li>
    <li><strong>避免单线程单元 (STA) COM 组件</strong><br />
    　　默认情况下，ASP.NET 不允许任何 STA COM 组件在页面内运行。若要运行它们，必须在 .aspx 文件内将 ASPCompat=true 属性包含在 @ Page 指令中。这样就将执行用的线程池切换到 STA 线程池，而且使 HttpContext 和其他内置对象可用于 COM 对象。前者也是一种性能优化，因为它避免了将多线程单元 (MTA) 封送到 STA 线程的任何调用。使用 STA COM 组件可能大大损害性能，应尽量避免。若必须使用 STA COM 组件，如在任何 interop 方案中，则应在执行期间进行大量调用并在每次调用期间发送尽可能多的信息。另外，小心不要在构造页面期间创建任何 STA COM 组件。例如下面的代码中，在页面构造时将实例化由某个线程创建的 MySTAComponent，而该线程并不是将运行页面的 STA 线程。这可能对性能有不利影响，因为要构造页面就必须完成 MTA 和 STA 线程之间的封送处理。<br />
    <div class="quote">&lt;%@ Page Language="VB" ASPCompat="true" %&gt;<br />
    &lt;script runat=server&gt;<br />
    Dim myComp as new MySTAComponent()<br />
    Public Sub Page_Load()<br />
    myComp.Name = "Bob"<br />
    End Sub<br />
    &lt;/script&gt;<br />
    &lt;html&gt;<br />
    &lt;%<br />
    Response.Write(myComp.SayHello)<br />
    %&gt;<br />
    &lt;/html&gt;</div>
    <br />
    　　首选机制是推迟对象的创建，直到以后在 STA 线程下执行上述代码，如下面的例子所示。<br />
    <div class="quote">&lt;%@ Page Language="VB" ASPCompat="true" %&gt;<br />
    &lt;script runat=server&gt;<br />
    Dim myComp<br />
    Public Sub Page_Load()<br />
    myComp = new MySTAComponent()<br />
    myComp.Name = "Bob"<br />
    End Sub<br />
    &lt;/script&gt;<br />
    &lt;html&gt;<br />
    &lt;%<br />
    Response.Write(myComp.SayHello)<br />
    %&gt;<br />
    &lt;/html&gt;<br />
    </div>
    　　推荐的做法是在需要时或者在 Page_Load 方法中构造任何 COM 组件和外部资源。永远不要将任何 STA COM 组件存储在可以由构造它的线程以外的其他线程访问的共享资源里。这类资源包括像缓存和会话状态这样的资源。即使 STA 线程调用 STA COM 组件，也只有构造此 STA COM 组件的线程能够实际为该调用服务，而这要求封送处理对创建者线程的调用。此封送处理可能产生重大的性能损失和可伸缩性问题。在这种情况下，请研究一下使 COM 组件成为 MTA COM 组件的可能性，或者更好的办法是迁移代码以使对象成为托管对象。</li>
    <li><strong>将调用密集型的 COM 组件迁移到托管代码</strong><br />
    　　.NET Framework 提供了一个简单的方法与传统的 COM 组件进行交互。其优点是可以在保留现有投资的同时利用新的平台。但是在某些情况下，保留旧组件的性能开销使得将组件迁移到托管代码是值得的。每一情况都是不一样的，决定是否需要迁移组件的最好方法是对 Web 站点运行性能测量。建议您研究一下如何将需要大量调用以进行交互的任何COM 组件迁移到托管代码。许多情况下不可能将旧式组件迁移到托管代码，特别是在最初迁移 Web 应用程序时。在这种情况下，最大的性能障碍之一是将数据从非托管环境封送到托管环境。因此，在交互操作中，请在任何一端执行尽可能多的任务，然后进行一个大调用而不是一系列小调用。例如，公共语言运行库中的所有字符串都是 Unicode 的，所以应在调用托管代码之前将组件中的所有字符串转换成 Unicode 格式。另外，一处理完任何 COM 对象或本机资源就释放它们。这样，其他请求就能够使用它们，并且最大限度地减少了因稍后请求垃圾回收器释放它们所引起的性能问题。</li>
    <li><strong>在 Visual Basic .NET 或 JScript. 代码中使用早期绑定<br />
    </strong>　　以往，开发人员喜欢使用 Visual Basic、VBScript. 和 JScript. 的原因之一就是它们所谓&#8220;无类型&#8221;的性质。变量不需要显式类型声明，并能够简单地通过使用来创建它们。当从一个类型到另一个类型进行分配时，转换将自动执行。不过，这种便利会大大损害应用程序的性能。Visual Basic 现在通过使用 Option Strict 编译器指令来支持类型安全编程。为了向后兼容，默认情况下，ASP.NET 不启用该选项。但是，为了得到最佳性能，强烈建议在页中启用该选项。若要启用 Option Strict，请将 Strict 属性包括在 @ Page 指令中，或者，对于用户控件，请将该属性包括在 @ Control 指令中。下面的示例演示了如何设置该属性，并进行了四个变量调用以显示使用该属性是如何导致编译器错误的。<br />
    <div class="quote">&lt;%@ Page Language="VB" Strict="true" %&gt;<br />
    &lt;%<br />
    Dim B<br />
    Dim C As String<br />
    ' This will cause a compiler error.<br />
    A = "Hello"<br />
    ' This will cause a compiler error.<br />
    B = "World"<br />
    ' This will not cause a compiler error.<br />
    C = "!!!!!!"<br />
    ' But this will cause a compiler error.<br />
    C = 0<br />
    %&gt;　　Dim B<br />
    Dim C As String<br />
    ' This will cause a compiler error.<br />
    A = "Hello"<br />
    ' This will cause a compiler error.<br />
    B = "World"<br />
    ' This will not cause a compiler error.<br />
    C = "!!!!!!"<br />
    ' But this will cause a compiler error.<br />
    C = 0<br />
    %&gt;<br />
    </div>
    　　JScript.NET 也支持无类型编程，但它不提供强制早期绑定的编译器指令。若发生下面任何一种情况，则变量是晚期绑定的：被显式声明为 Object，是无类型声明的类的字段，是无显式类型声明的专用函数或方法成员，并且无法从其使用推断出类型。 　　最后一个差别比较复杂，因为如果 JScript. .NET 编译器可以根据变量的使用情况推断出类型，它就会进行优化。在下面的示例中，变量 A 是早期绑定的，但变量 B 是晚期绑定的。<br />
    <div class="quote">var A;<br />
    var B;<br />
    A = "Hello";<br />
    B = "World";<br />
    B = 0;</div>
    <br />
    　　为了获得最佳的性能，当声明 JScript. .NET 变量时，请为其分配一个类型。例如，var A : String。</li>
    <li><strong>使请求管线内的所有模块尽可能高效<br />
    </strong>　　请求管线内的所有模块在每次请求中都有机会被运行。因此，当请求进入和离开模块时快速地触发代码至关重要，特别是在不使用模块功能的代码路径里。分别在使用及不使用模块和配置文件时执行吞吐量测试，对确定这些方法的执行速度非常有用。</li>
    <li><strong>使用 HttpServerUtility.Transfer 方法在同一应用程序的页面间重定向</strong><br />
    　　采用 Server.Transfer 语法，在页面中使用该方法可避免不必要的客户端重定向。</li>
    <li><strong>必要时调整应用程序每个辅助进程的线程数</strong><br />
    　　ASP.NET 的请求结构试图在执行请求的线程数和可用资源之间达到一种平衡。已知一个使用足够 CPU 功率的应用程序，该结构将根据可用于请求的 CPU 功率，来决定允许同时执行的请求数。这项技术称作线程门控。但是在某些条件下，线程门控算法不是很有效。通过使用与 ASP.NET Applications 性能对象关联的 Pipeline Instance Count 性能计数器，可以在 PerfMon 中监视线程门控。当页面调用外部资源，如数据库访问或 XML Web services 请求时，页面请求通常停止并释放 CPU。如果某个请求正在等待被处理，并且线程池中有一个线程是自由的，那么这个正在等待的请求将开始被处理。遗憾的是，有时这可能导致 Web 服务器上存在大量同时处理的请求和许多正在等待的线程，而它们对服务器性能有不利影响。通常，如果门控因子是外部资源的响应时间，则让过多请求等待资源，对 Web 服务器的吞吐量并无帮助。为缓和这种情况，可以通过更改 Machine.config 配置文件节点的 maxWorkerThreads 和 maxIOThreads 属性，手动设置进程中的线程数限制。<br />
    　　注意：辅助线程是用来处理 ASP.NET 请求的，而 IO 线程则是用于为来自文件、数据库或 XML Web services 的数据提供服务的。分配给这些属性的值是进程中每个 CPU 每类线程的最大数目。对于双处理器计算机，最大数是设置值的两倍。对于四处理器计算机，最大值是设置值的四倍。无论如何，对于有四个或八个 CPU 的计算机，最好更改默认值。对于有一个或两个处理器的计算机，默认值就可以，但对于有更多处理器的计算机的性能，进程中有一百或两百个线程则弊大于利。注意进程中有太多线程往往会降低服务器的速度，因为额外的上下文交换导致操作系统将 CPU 周期花在维护线程而不是处理请求上。</li>
    <li><strong>适当地使用公共语言运行库的垃圾回收器和自动内存管理</strong><br />
    　　小心不要给每个请求分配过多内存，因为这样垃圾回收器将必须更频繁地进行更多的工作。另外，不要让不必要的指针指向对象，因为它们将使对象保持活动状态，并且应尽量避免含 Finalize 方法的对象，因为它们在后面会导致更多的工作。特别是在 Finalize 调用中永远不要释放资源，因为资源在被垃圾回收器回收之前可能一直消耗着内存。最后这个问题经常会对 Web 服务器环境的性能造成毁灭性的打击，因为在等待 Finalize 运行时，很容易耗尽某个特定的资源。</li>
    <li><strong>如果有大型 Web 应用程序，可考虑执行预批编译</strong><br />
    　　每当发生对目录的第一次请求时都会执行批编译。如果目录中的页面没有被分析并编译，此功能会成批分析并编译目录中的所有页面，以便更好地利用磁盘和内存。如果这需要很长时间，则将快速分析并编译单个页面，以便请求能被处理。此功能带给 ASP.NET 性能上的好处，因为它将许多页面编译为单个程序集。从已加载的程序集访问一页比每页加载新的程序集要快。批编译的缺点在于：如果服务器接收到许多对尚未编译的页面的请求，那么当 Web 服务器分析并编译它们时，性能可能较差。为解决这个问题，可以执行预批编译。为此，只需在应用程序激活之前向它请求一个页面，无论哪页均可。然后，当用户首次访问您的站点时，页面及其程序集将已被编译。没有简单的机制可以知道批编译何时发生。需一直等到 CPU 空闲或者没有更多的编译器进程(例如 csc.exe(C# 编译器)或 vbc.exe(Visual Basic 编译器))启动。还应尽量避免更改应用程序的 bin 目录中的程序集。更改页面会导致重新分析和编译该页，而替换 bin 目录中的程序集则会导致完全重新批编译该目录。在包含许多页面的大规模站点上，更好的办法可能是根据计划替换页面或程序集的频繁程度来设计不同的目录结构。不常更改的页面可以存储在同一目录中并在特定的时间进行预批编译。经常更改的页面应在它们自己的目录中(每个目录最多几百页)以便快速编译。Web 应用程序可以包含许多子目录。批编译发生在目录级，而不是应用程序级。</li>
    <li><strong>不要依赖代码中的异常</strong><br />
    　　因为异常大大地降低性能，所以您不应该将它们用作控制正常程序流程的方式。如果有可能检测到代码中可能导致异常的状态，请执行这种操作。不要在处理该状态之前捕获异常本身。常见的方案包括：检查 null，分配给将分析为数字值的 String 一个值，或在应用数学运算前检查特定值。下面的示例演示可能导致异常的代码以及测试是否存在某种状态的代码。两者产生相同的结果。<br />
    <div class="quote">try<br />
    {<br />
    　result = 100 / num;<br />
    }<br />
    catch (Exception e)<br />
    {<br />
    　result = 0;<br />
    }<br />
    // ...to this.<br />
    if (num != 0)<br />
    　result = 100 / num;<br />
    else<br />
    　result = 0;</div>
    </li>
    <li><strong>使用 HttpResponse.Write 方法进行字符串串联</strong><br />
    　　该方法提供非常有效的缓冲和连接服务。但是，如果您正在执行广泛的连接，请使用多个 Response.Write 调用。下面示例中显示的技术比用对 Response.Write 方法的单个调用连接字符串更快。<br />
    <div class="quote">Response.Write("a");<br />
    Response.Write(myString);<br />
    Response.Write("b");<br />
    Response.Write(myObj.ToString());<br />
    Response.Write("c");<br />
    Response.Write(myString2);<br />
    Response.Write("d");</div>
    </li>
    <li><strong>除非有特殊的原因要关闭缓冲，否则使其保持打开</strong><br />
    　　禁用 Web 窗体页的缓冲会导致大量的性能开销。</li>
    <li><strong>只在必要时保存服务器控件视图状态</strong><br />
    　　自动视图状态管理是服务器控件的功能，该功能使服务器控件可以在往返过程上重新填充它们的属性值(您不需要编写任何代码)。但是，因为服务器控件的视图状态在隐藏的窗体字段中往返于服务器，所以该功能确实会对性能产生影响。您应该知道在哪些情况下视图状态会有所帮助，在哪些情况下它影响页的性能。例如，如果您将服务器控件绑定到每个往返过程上的数据，则将用从数据绑定操作获得的新值替换保存的视图状态。在这种情况下，禁用视图状态可以节省处理时间。默认情况下，为所有服务器控件启用视图状态。若要禁用视图状态，请将控件的EnableViewState 属性设置为 false，如下面的 DataGrid 服务器控件示例所示。<br />
    　　&lt;asp:datagrid EnableViewState="false" datasource="..." runat="server"/&gt;<br />
    　　您还可以使用 @ Page 指令禁用整个页的视图状态。当您不从页回发到服务器时，这将十分有用：<br />
    　　&lt;%@ Page EnableViewState="false" %&gt;<br />
    　　注意:@ Control 指令中也支持 EnableViewState 属性，该指令允许您控制是否为用户控件启用视图状态。若要分析页上服务器控件使用的视图状态的数量，请(通过将 trace="true" 属性包括在 @ Page 指令中)启用该页的跟踪并查看 Control Hierarchy 表的 Viewstate 列。有关跟踪和如何启用它的信息，请参见 ASP.NET 跟踪。</li>
    <li><strong>避免到服务器的不必要的往返过程</strong><br />
    　　虽然您很可能希望尽量多地使用 Web 窗体页框架的那些节省时间和代码的功能，但在某些情况下却不宜使用 ASP.NET 服务器控件和回发事件处理。通常，只有在检索或存储数据时，您才需要启动到服务器的往返过程。多数数据操作可在这些往返过程间的客户端上进行。例如，从 HTML 窗体验证用户输入经常可在数据提交到服务器之前在客户端进行。通常，如果不需要将信息传递到服务器以将其存储在数据库中，那么您不应该编写导致往返过程的代码。如果您开发自定义服务器控件，请考虑让它们为支持 ECMAScript. 的浏览器呈现客户端代码。通过以这种方式使用服务器控件，您可以显著地减少信息被不必要的发送到 Web 服务器的次数。<br />
    　　使用 Page.IsPostBack 避免对往返过程执行不必要的处理<br />
    　　如果您编写处理服务器控件回发处理的代码，有时可能需要在首次请求页时执行其他代码，而不是当用户发送包含在该页中的 HTML 窗体时执行的代码。根据该页是否是响应服务器控件事件生成的。<br />
    　　使用 Page.IsPostBack 属性有条件地执行代码<br />
    　　例如，下面的代码演示如何创建数据库连接和命令，该命令在首次请求该页时将数据绑定到 DataGrid 服务器控件。<br />
    <div class="quote">void Page_Load(Object sender, EventArgs e)<br />
    {<br />
    // Set up a connection and command here.<br />
    if (!Page.IsPostBack)<br />
    {<br />
    　String query = "select * from Authors where FirstName like '%JUSTIN%'";<br />
    　myCommand.Fill(ds, "Authors");<br />
    　myDataGrid.DataBind();<br />
    }<br />
    }</div>
    <br />
    　　由于每次请求时都执行 Page_Load 事件，上述代码检查 IsPostBack 属性是否设置为 false。如果是，则执行代码。如果该属性设置为 true，则不执行代码。注意 如果不运行这种检查，回发页的行为将不更改。Page_Load 事件的代码在执行服务器控件事件之前执行，但只有服务器控件事件的结果才可能在输出页上呈现。如果不运行该检查，仍将为 Page_Load 事件和该页上的任何服务器控件事件执行处理。</li>
    <li><strong>当不使用会话状态时禁用它</strong><br />
    　　并不是所有的应用程序或页都需要针对于具体用户的会话状态，您应该对任何不需要会话状态的应用程序或页禁用会话状态。 　　若要禁用页的会话状态，请将 @ Page 指令中的 EnableSessionState 属性设置为 false。例如:<br />
    　　&lt;%@ Page EnableSessi %&gt;<br />
    　　注意:如果页需要访问会话变量，但不打算创建或修改它们，则将@ Page 指令中的 EnableSessionState 属性设置为ReadOnly。还可以禁用 XML Web services 方法的会话状态。有关更多信息，请参见使用 ASP.NET 和 XML Web services 客户端创建的 XML Web services。若要禁用应用程序的会话状态，请在应用程序 Web.config 文件的 sessionstate 配置节中将 mode 属性设置为 off。例如:<br />
    　　&lt;sessionstate mode="off" /&gt;</li>
    <li><strong>仔细选择会话状态提供程序</strong><br />
    　　ASP.NET 为存储应用程序的会话数据提供了三种不同的方法：进程内会话状态、作为 Windows 服务的进程外会话状态和 SQL Server 数据库中的进程外会话状态。每种方法都有自己的优点，但进程内会话状态是迄今为止速度最快的解决方案。如果只在会话状态中存储少量易失数据，则建议您使用进程内提供程序。进程外解决方案主要用于跨多个处理器或多个计算机缩放应用程序，或者用于服务器或进程重新启动时不能丢失数据的情况。有关更多信息，请参见 ASP.NET 状态管理。</li>
    <li><strong>不使用不必要的Server Control</strong><br />
    　　ASP.net中，大量的服务器端控件方便了程序开发，但也可能带来性能的损失，因为用户每操作一次服务器端控件，就产生一次与服务器端的往返过程。因此，非必要，应当少使用Server Control。</li>
    <li><strong>ASP.NET应用程序性能测试</strong><br />
    　　在对ASP.NET应用程序进行性能测试之前，应确保应用程序没有错误，而且功能正确。具体的性能测试可以采用以下工具进行：Web Application Strees Tool (WAS)是Microsoft发布的一个免费测试工具，可以从<a title="" href="http://webtool.rte.microsoft.com/" target="_blank">http://webtool.rte.microsoft.com/</a>上下载。它可以模拟成百上千个用户同时对web应用程序进行访问请求，在服务器上形成流量负载，从而达到测试的目的，可以生成平均TTFB、平均TTLB等性能汇总报告。 Application Center Test (ACT) 是一个测试工具，附带于Visual Studio.NET的企业版中，是Microsoft正式支持的web应用程序测试工具。它能够直观地生成图表结果，功能比WAS多，但不具备多个客户机同时测试的能力。服务器操作系统"管理工具"中的"性能"计数器，可以对服务器进行监测以了解应用程序性能。</li>
</ol>
<p>　　<strong>结论</strong>：<br />
　　对于网站开发人员来说，在编写ASP.NET应用程序时注意性能问题，养成良好的习惯，提高应用程序性能，至少可以推迟必需的硬件升级，降低网站的成本。</p>
 <img src ="http://www.cnblogs.com/9who/aggbug/1271585.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41822/" target="_blank">[新闻]第一财经周刊:当前互联网世界正处无秩序时代</a>]]></description></item><item><title>网易娱乐频道也在用风讯CMS</title><link>http://www.cnblogs.com/9who/archive/2008/08/14/1267714.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Thu, 14 Aug 2008 04:10:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/08/14/1267714.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1267714.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/08/14/1267714.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1267714.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1267714.html</trackback:ping><description><![CDATA[<p>最近在做一个cms，参考了风讯.net cms ，发现<font face="Verdana">网易娱乐频道也在用风讯CMS</font></p>
<p>大家打开下列链接看看：<br />
<a href="http://ent.163.com/08/0710/05/4GFGDSJU00032DGD.html" target="_blank">http://ent.163.com/08/0710/05/4GFGDSJU00032DGD.html</a><br />
打开一看：<br />
<img class="lightbox" style="oldpaddingtop: ; oldbordertopwidth: ; oldpaddingbottom: ; oldborderbottomwidth: ; oldpaddingright: ; oldborderrightwidth: ; oldpaddingleft: ; oldborderleftwidth: " alt="" src="http://www.youxia.org/upload/2008/7/200807131523012762.gif" /><br />
用过风讯的都晓得吧？呵呵。<br />
其实风讯CMS很好用的，上手容易、入门快，自己最喜欢的CMS之一。 </p>
<p class="cloudreamHelperLink" style="display: none" codetype="post" entryid="671">这个没有网易的人吧，呵呵</p>
<p class="cloudreamHelperLink" style="display: none" codetype="post" entryid="671">转载网络</p>
<script src="http://www.youxia.org/PLUGIN/copytofriends/copy.js" type="text/javascript"></script>
 <img src ="http://www.cnblogs.com/9who/aggbug/1267714.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41820/" target="_blank">[新闻]Visual Studio 2008 SDK 1.1 发布</a>]]></description></item><item><title>CSS基本布局16例</title><link>http://www.cnblogs.com/9who/archive/2008/08/11/1265351.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Mon, 11 Aug 2008 08:44:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/08/11/1265351.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1265351.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/08/11/1265351.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1265351.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1265351.html</trackback:ping><description><![CDATA[<p>这段时间是一直在学习 div+css布局，感觉这段挺实用的，转了过来，</p>
<p>以下布局资料原作者：<a href="http://www.thenoodleincident.com/tutorials/box_lesson/boxes.html" target="new"><font color="#60a179">Owen Briggs</font></a></p>
<h4>单行单列</h4>
<ul>
    <li><a title="链接到单行单列" href="http://www.w3cn.org/article/layout/2004/csslayout/onebox.html" target="new" rel="next"><img height="50" alt="单行单列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/1box.gif" width="50" /><font color="#60a179"> 单行单列1</font></a>：采用float浮在左上角，固定宽度。</li>
    <li><a title="链接到单行单列" href="http://www.w3cn.org/article/layout/2004/csslayout/onebox_absolute.html" target="new" rel="next"><img height="50" alt="单行单列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/1box.gif" width="50" /><font color="#60a179"> 单行单列2</font></a>：固定在左上角，固定宽度，采用的是绝对(absolute)定位。</li>
    <li><a title="链接到单行单列" href="http://www.w3cn.org/article/layout/2004/csslayout/onebox_fluid.html" target="new" rel="next"><img height="50" alt="单行单列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/1box.gif" width="50" /><font color="#60a179"> 单行单列3</font></a>：固定在左上角，不固定宽度，采用百分比(%)定义宽度来自适应页面。</li>
    <li><a title="链接到单行单列" href="http://www.w3cn.org/article/layout/2004/csslayout/onebox_centent.html" target="new" rel="next"><img height="50" alt="单行单列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/1box_centered.gif" width="50" /><font color="#60a179"> 单行单列4</font></a>(推荐)：固定宽度，采用在body样式中定义居中属性(text-align: center;)实现适应页面自动居中。 </li>
</ul>
<h4>单行两列</h4>
<ul>
    <li><a title="链接到单行两列" href="http://www.w3cn.org/article/layout/2004/csslayout/twobox.html" target="new" rel="next"><img height="50" alt="单行两列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/2box.gif" width="50" /><font color="#60a179"> 单行两列1</font></a>：两列都固定宽度。第一列浮在左上角，第二列浮在第一列右边。</li>
    <li><a title="链接到单行两列" href="http://www.w3cn.org/article/layout/2004/csslayout/twobox_fluid.html" target="new" rel="next"><img height="50" alt="单行两列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/2box.gif" width="50" /><font color="#60a179"> 单行两列2</font></a>：两列都百分比宽度，但不满屏。第一列固定在左上角，第二列浮在第一列右边。</li>
    <li><a title="链接到单行两列" href="http://www.w3cn.org/article/layout/2004/csslayout/twobox_touch.html" target="new" rel="next"><img height="50" alt="单行两列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/2box_split.gif" width="50" /><font color="#60a179"> 单行两列3</font></a>：两列都百分比宽度，满屏。两列都采用绝对定位。</li>
    <li><a title="链接到单行两列" href="http://www.w3cn.org/article/layout/2004/csslayout/twobox_touch2.html" target="new" rel="next"><img height="50" alt="单行两列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/2box_split.gif" width="50" /><font color="#60a179"> 单行两列4</font></a>：两列都百分比宽度，满屏。第一列浮在左上角，第二列浮在右上角。</li>
    <li><a title="链接到单行两列" href="http://www.w3cn.org/article/layout/2004/csslayout/twobox_touch3.html" target="new" rel="next"><img height="50" alt="单行两列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/2box_split.gif" width="50" /><font color="#60a179"> 单行两列5</font></a>：两列都百分比宽度，满屏。第一列浮在左上角，第二列浮在第一列右边。 </li>
</ul>
<h4>单行三列</h4>
<ul>
    <li><a title="链接到单行三列" href="http://www.w3cn.org/article/layout/2004/csslayout/threebox.html" target="new" rel="next"><img height="50" alt="单行三列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/3column.gif" width="50" /><font color="#60a179"> 单行三列1</font></a>：左右列都绝对定位(右列定位在右上)。左列和右列固定宽度，中间列自适应页面。</li>
    <li><a title="链接到单行三列" href="http://www.w3cn.org/article/layout/2004/csslayout/threebox2.html" target="new" rel="next"><img height="50" alt="单行三列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/3column.gif" width="50" /><font color="#60a179"> 单行三列2</font></a>：左列定位在左上，右列定位在右上，中间列浮在左列右面。左列和右列固定宽度，中间列自适应页面。</li>
    <li><a title="链接到单行三列" href="http://www.w3cn.org/article/layout/2004/csslayout/threebox3.html" target="new" rel="next"><img height="50" alt="单行三列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/3column.gif" width="50" /><font color="#60a179"> 单行三列3</font></a>：三列都绝对定位。左列和右列固定宽度，中间列根据内容自适应。</li>
    <li><a title="链接到单行三列" href="http://www.w3cn.org/article/layout/2004/csslayout/threebox4.html" target="new" rel="next"><img height="50" alt="单行三列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/3column.gif" width="50" /><font color="#60a179"> 单行三列4</font></a>(推荐)：类似样式2，只是将margin: 20px属性增加在body样式中，解决了中间列在Netscape6.0中置顶的问题。</li>
    <li><a title="链接到单行三列" href="http://www.w3cn.org/article/layout/2004/csslayout/threebox_touch.html" target="new" rel="next"><img height="50" alt="单行三列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/3column_touche.gif" width="50" /><font color="#60a179"> 单行三列5</font></a>：左右列绝对定位，中间列自适应。宽度满屏。 </li>
</ul>
<h4>顶行三列</h4>
<ul>
    <li><a title="链接到顶行三列" href="http://www.w3cn.org/article/layout/2004/csslayout/fourbox.html" target="new" rel="next"><img height="50" alt="顶行三列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/3columnplusbox.gif" width="50" /><font color="#60a179"> 顶行三列1</font></a>(推荐)：顶行自适应页面宽度。左右列绝对定位，中间列自适应页面。</li>
    <li><a title="链接到顶行三列" href="http://www.w3cn.org/article/layout/2004/csslayout/fourbox_touch.html" target="new" rel="next"><img height="50" alt="顶行三列" src="http://www.w3cn.org/article/layout/2004/csslayout/images/3columnplusbox_toucha.gif" width="50" /><font color="#60a179"> 顶行三列2</font></a>：宽度满屏 <br class="clearer" />
    </li>
</ul>
<img src ="http://www.cnblogs.com/9who/aggbug/1265351.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41821/" target="_blank">[新闻]死敌VMware变身微软认证计划新成员</a>]]></description></item><item><title>CSS命名规范(建议版) </title><link>http://www.cnblogs.com/9who/archive/2008/08/11/1265314.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Mon, 11 Aug 2008 08:10:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/08/11/1265314.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1265314.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/08/11/1265314.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1265314.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1265314.html</trackback:ping><description><![CDATA[<div class="postBody"><span style="font-size: 10pt; color: #000080">非原创，来源网络。感谢原作者奉献如此精彩文章。原文地址：</span> <a href="http://bbs.blueidea.com/thread-2856346-1-1.html">http://bbs.blueidea.com/thread-2856346-1-1.html</a><br />
<br />
容&nbsp; &nbsp; 器：container/box <br />
头&nbsp; &nbsp; 部：header <br />
主 导 航：mainNav <br />
子 导 航：subNav <br />
顶 导 航：topNav <br />
网站标志：logo <br />
大 广 告：banner <br />
页面中部：mainBody <br />
底&nbsp; &nbsp; 部：footer <br />
菜&nbsp; &nbsp; 单：menu <br />
菜单内容：menuContent <br />
子 菜 单：subMenu <br />
子菜单内容：subMenuContent <br />
搜&nbsp; &nbsp; 索：search <br />
搜索关键字：keyword <br />
搜索范围：range <br />
标签文字：tagTitle <br />
标签内容：tagContent <br />
当前标签：tagCurrent/currentTag <br />
标　&nbsp;&nbsp;题：title <br />
内&nbsp; &nbsp; 容：content <br />
列&nbsp; &nbsp; 表：list <br />
当前位置：currentPath <br />
侧 边 栏：sidebar <br />
图&nbsp; &nbsp; 标：icon <br />
注&nbsp; &nbsp; 释：note <br />
登&nbsp; &nbsp; 录：login <br />
注&nbsp; &nbsp; 册：register <br />
列 定 义：column_1of3 (三列中的第一列)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;column_2of3 (三列中的第二列)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;column_3of3 (三列中的第三列)<br />
<br />
外　套：　　wrap<br />
主导航：　　mainnav<br />
子导航：　　subnav<br />
页　脚：　　footer<br />
整个页面：　content<br />
页　眉：　　header<br />
页　脚：　　footer<br />
商　标：　　label<br />
标　题：　　title<br />
主导航：　　mainbav（globalnav）<br />
顶导航：　　topnav<br />
边导航：　　sidebar<br />
左导航：　　leftsidebar<br />
右导航：　　rightsidebar<br />
旗　志：　　logo<br />
标　语：　　banner<br />
菜单内容1： menu1 content<br />
菜单容量：　menu container<br />
子菜单：　　submenu<br />
边导航图标：sidebarIcon<br />
注释：　　　note<br />
面包屑：　　breadcrumb(即页面所处位置导航提示）<br />
容器：　　　container<br />
内容：　　　content<br />
搜索：　　　search<br />
登陆：　　　Login<br />
功能区：　　shop(如购物车，收银台)<br />
当前的　　　current<br />
<br />
2.另外在编辑样式表时可用的注释可这样写：<br />
&lt;-- Footer --&gt;<br />
内容区<br />
&lt;-- End Footer --&gt;<br />
<br />
3.样式文件命名<br />
主要的 master.css<br />
布局，版面 layout.css<br />
专栏 columns.css<br />
文字 font.css<br />
打印样式 print.css<br />
主题 themes.css <br />
</div>
<img src ="http://www.cnblogs.com/9who/aggbug/1265314.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41821/" target="_blank">[新闻]死敌VMware变身微软认证计划新成员</a>]]></description></item><item><title>web布局最实用的12条css技巧 </title><link>http://www.cnblogs.com/9who/archive/2008/08/11/1265300.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Mon, 11 Aug 2008 07:54:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/08/11/1265300.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1265300.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/08/11/1265300.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1265300.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1265300.html</trackback:ping><description><![CDATA[摘要: 1：Rounded corners without images效果图——Rounded corners without images&lt;divid=&#8221;container&#8221;&gt;&lt;bclass=&#8221;rtop&#8221;&gt;&lt;bclass=&#8221;r1&#8243;&gt;&lt;/b&gt;&lt;bclass=&#8221;r2&#&nbsp;&nbsp;<a href='http://www.cnblogs.com/9who/archive/2008/08/11/1265300.html'>阅读全文</a><img src ="http://www.cnblogs.com/9who/aggbug/1265300.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41821/" target="_blank">[新闻]死敌VMware变身微软认证计划新成员</a>]]></description></item><item><title>SQL2005数据库转换到SQL2000</title><link>http://www.cnblogs.com/9who/archive/2008/08/11/1264911.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Mon, 11 Aug 2008 01:50:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/08/11/1264911.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1264911.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/08/11/1264911.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1264911.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1264911.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;最近做了个项目，采用了sql2005做的，但我的空间数据库库只提供sql2000的，于是就想了转到sql2000，可不可以？</p>
<p>具体猜想的过程就是在sql2005中生成sql2000的sql 脚本，然后在sql2000中新建目标库，在sql 2000查询分析器中，执行生成的脚本。</p>
<p>这样数据库我们就生成成功了，下一步就是把sql2005的数据导出到sql2000中，同样在sql2005选择目标数据库，右击任务我们选择要导出到sql2000库即可。</p>
<p>大体思想就是这样，我在网上搜了一下有人写了这方面的文章，不写了，下面引用了下来：</p>
<p style="background-color: yellow">直接restore或附加应该是不行的, 用脚本+导数据肯定没有问题。<br />
<br />
2005转到2000的步骤<br />
1. 生成for 2000版本的数据库脚本<br />
2005 的manger studio<br />
-- 打开"对象资源管理器"(没有的话按F8), 连接到你的实例<br />
-- 右键要转到2000的库<br />
-- 任务<br />
-- 生成脚本<br />
-- 在"脚本向导"的"选择数据库"中, 确定选择的是要转到2000的库<br />
-- 勾选"为所选数据库中的所有对象编写脚本"<br />
-- 在接下来的"选择脚本选项"中, 找到"为服务器版本编写脚本"项, 选择"SQL Server 2000"<br />
-- 其他选项根据需要设置<br />
-- 最后把脚本保存到一个 .sql 脚本文件<br />
<br />
2. 在2000中创建目标数据库<br />
在查询分析器(或2005的manger studio在打开脚本文件), 连接到SQL Server 2000,执行上面生成的脚本.以创建一个新的数据库<br />
<br />
3. 将数据从2005导到2000<br />
2005 的manger studio<br />
-- 打开"对象资源管理器"(没有的话按F8), 连接到你的实例<br />
-- 右键要转到2000的库<br />
-- 任务<br />
-- 导出数据<br />
-- 在"SQL Server 导入和导出向导"的"选择数据源"步骤中, 确定选择的是要导出的数据库<br />
-- 在"选择目标"步骤中, 连接到 2000, 并选择步骤2新建的库<br />
-- 在"选择源表和源视图"中, 选择所有的表<br />
-- 最后完成</p>
 <img src ="http://www.cnblogs.com/9who/aggbug/1264911.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41821/" target="_blank">[新闻]死敌VMware变身微软认证计划新成员</a>]]></description></item><item><title>我的几个.NET编程习惯</title><link>http://www.cnblogs.com/9who/archive/2008/08/08/1263395.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Fri, 08 Aug 2008 00:53:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/08/08/1263395.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1263395.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/08/08/1263395.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1263395.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1263395.html</trackback:ping><description><![CDATA[<p>类：</p>
<p>1、类属性的命名以单词第一个字母大写开始，类的私有变量以下划线加单词第一个字母小写开始。这样的话我们在方法中传递参数的时候，参数变量就可以命名成以单词第一个字母小写开始，调用的时候很容易明白其含义，而且不会和类的私有成员冲突。</p>
<p>2、&nbsp;除了控件的命名，变量命名的方法不再使用匈牙利命名法，而为变量使用一个更具有代表意义的名字。控件变量前适当的加入小写缩写可以有效的区分控件的类型。</p>
<p>3、&nbsp;所有的类、方法和属性都做了XML注释。这种注释可以在类或方法等声明的前一行输入&#8220;///&#8221;自动生成注释格式，做类库程序的时候可以通过类库属性，生成里选择&#8220;XML 文档文件&#8221;，为项目指定输出XML注释的文档路径，并且利用 Sandcastle 为类库生成文档。</p>
<p>4、&nbsp;尽量将一些常用的功能模块封装成类，并做成不同的类库，生成XML注释稳当，生成CHM格式的文档。这样下次用的时候就不必到处找这个模块了，只要引用相应的程序集就好了，而且.NET IDE 在你调用类库中的类时还能为你读取XML注释，实在忘记了还能看看 CHM 文档。日积月累这些DLL将成为你一笔很大的财富。</p>
<p>&nbsp;这点可以参照我收集的类库 ：<a href="http://www.cnblogs.com/9who/category/103884.html">点击 访问</a></p>
<p>执行效率：</p>
<p>&nbsp;1、for 和 foreach 我更喜欢for。用 foreach 编写的代码块反编译成IL后会发现其中加入了try块，而且很容易看出来效率要比for稍低。</p>
<p>2、&nbsp;不再使用&#8220;+&#8221; 号来连接多个字符串，而是采用 StringBuilder 的 Append 方法，这样会提高效率。关于这个问题读者可以参考一下与.NET 装相相关的文章。</p>
<p>3.虽然 DataSet 很好用，但是我不喜欢用 DataSet。ADO.NET 隐藏了一个令人讨厌的秘密：这个了不起的新技术对所有的分布式应用程序都不适用。DataSet 很大，用的不好可能会导致系统变慢，而且很容易产生并发冲突。能用DataReader 就不用DataSet。</p>
<p><span style="color: red"><span style="color: red"><span style="color: #339966">在这里说一下 DataSet和DataReader 区别</span></span></span></p>
<p><span style="color: red"><span style="color: red"><span style="color: #339966"><span style="color: #339966"><span style="color: #339966">使用 &nbsp; SqlDataReader &nbsp; 获得快进只读数据游标：&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp; SqlDataReader &nbsp; 对象对从 &nbsp; SQL &nbsp; 数据库中检索的数据提供前进只读游标。 &nbsp; <br />
&nbsp; 如果 &nbsp; SqlDataReader &nbsp; 适合于您的情况，则它是一个比 &nbsp; DataSet &nbsp; 更好的选择。 &nbsp; <br />
&nbsp; 因为 &nbsp; SqlDataReader &nbsp; 支持 &nbsp; IEnumerable &nbsp; 接口，甚至还可以绑定服务器控件。</span></span></span></span></span></p>
<p><span style="color: red"><span style="color: red"><span style="color: #339966">DataSet是一次把数据全取出来放在内存中,&nbsp;&nbsp; DataReader只能一次次地读取数据, &nbsp; 方便读取少量数据时使用。</span></span></span></p>
<p><span style="color: red"><span style="color: red"><span style="color: #000000">4.对需要释放资源的类要实现 IDispose 接口，并使用 using 语句块来访问资源，这样的话有利于垃圾回收。</span></span></span></p>
<p><span style="color: red"><span style="color: red"><span style="color: #000000">我喜欢用DataReader,不喜欢将访问数据库类的方法都写成静态的。虽然适当的使用静态方法能够提高程序的运行效率，但是为了避免忘记关闭数据库带来的不必要的麻烦，我还是选择了实现IDispose接口并使用using 块访问数据库的方法。</span></span></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<img src ="http://www.cnblogs.com/9who/aggbug/1263395.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41819/" target="_blank">[新闻]英特尔雅虎开发网络计算机频道</a>]]></description></item><item><title>SQL2005示例数据库|AdventureWorks下载安装|NORTHWND下载安装|PUBS下载安装</title><link>http://www.cnblogs.com/9who/archive/2008/08/07/1262580.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Thu, 07 Aug 2008 01:24:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/08/07/1262580.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1262580.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/08/07/1262580.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1262580.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1262580.html</trackback:ping><description><![CDATA[<p>sql2005数据库实例 从网上找还得麻烦，转了过来，点击就可以下载！</p>
<p>在学习SQL2005中离开不了<a title="SQL2005示例数据库" href="http://www.cngothic.com/20080226/sql-2005-adventureworks-northwind-pubs.html">SQL2005示例数据库</a>，<a title="AdventureWorks数据库下载" href="http://www.cngothic.com/old_file/SQL-2005-datebase.rar">AdventureWorks数据库下载</a>安装，，<a title="northwind数据库下载" href="http://www.cngothic.com/old_file/SQL-2005-datebase.rar">northwind数据库下载安装</a>，，<a title="PUBS数据库下载" href="http://www.cngothic.com/old_file/SQL-2005-datebase.rar">PUBS数据库下载</a>安装。微软上的AdventureWorks,northwind,PUBS三库下载地址难找且又是E言文今天上传方便使用。<br />
下载完SQL 2005示例库。解压后里面有两个文件夹 AdventureWorks 与 northwind</p>
<p><strong>AdventureWorks数据库 安装使用方法：</strong></p>
<p>在AdventureWorks文件夹下面有文件 AdventureWorksDB.msi。双击安装。<br />
后打把此数据库附加到数据SQL 2005内。AdventureWorksDB.dbf的位置为：<br />
C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\AdventureWorks_Data.mdf<br />
我的 SQL 2005 安装在C:\Program Files\（即安装SQL 2005的默认安装路径）<br />
到此步 AdventureWorks 安装完成。</p>
<p><strong>northwind数据库，PUBS数据库 安装使用方法：</strong></p>
<p>在northwind文件夹下面有文件 SQL2000SampleDb.msi。双击安装。<br />
默认安装路径为：C:\SQL Server 2000 Sample Databases<br />
里面包括 northwind数据库，PUBS数据库 与 northwind数据库，PUBS数据库 的SQL脚本文件<br />
运行查询或附加数据库任选。Cngothic 采用附加的方法。把两库附加到SQL中。<br />
到此结束。</p>
<img src ="http://www.cnblogs.com/9who/aggbug/1262580.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41818/" target="_blank">[新闻]Windows Live视频邮件9月9日开始测试</a>]]></description></item><item><title>(转）Ext与.NET超完美整合 .NET开发者的超级优势</title><link>http://www.cnblogs.com/9who/archive/2008/08/06/1262279.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Wed, 06 Aug 2008 09:51:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/08/06/1262279.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1262279.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/08/06/1262279.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1262279.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1262279.html</trackback:ping><description><![CDATA[<p>回顾学习EXT的过程，自己一直从事.NET快速开发（不喜欢JAVA平台比较乱的Jar包，版本控制力太差）。EXT虽然是纯UI东东，但似乎跟JAVA一直有着亲蜜的关系，找的所有成型点的例子中，跟JAVA的居多，用WebService和ASP的都非常不适用，Ext的界面设计非常方便，但通信起来，只有用JSON或XML等中间件来传递，存在解译成本和传递成本，WebService即要花N多安全功夫，效率也很低，加上用LINQ镜像延时，用.net来做EXT实在很痛苦，跟ASPX淘汰的刷新机制无太大差别。<font color="#ff6600">今天我就是来解放大家的</font></p>
<p>我喜欢EXT，终于想到了一个超完美的整合</p>
<p>1。VS2008支持JS单步调试，可设断点调试JS，（不用代码提示，可以提高自己的熟练度，自己看看要不要在VS2008里面加代码提示的JS文件吧）</p>
<p>2。母版将所有JS调用全定义好</p>
<p>&lt;%@ Master Language="C#" AutoEventWireup="true" CodeFile="Ext2Empty.master.cs" Inherits="tmksoft.Web.Ext2Empty" %&gt;<br />
&lt;html&gt;<br />
&lt;head runat="server"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;title&gt;TMKSOFT CRM V2.0&lt;/title&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;script type="text/javascript"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var BaseUrl = "&lt;%=BaseUrl%&gt;";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/script&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;link rel="stylesheet" type="text/css" href="../Javascript/ext/resources/css/ext-all.css" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;script type="text/javascript" src="&lt;%=BaseUrl%&gt;Javascript/ext/adapter/ext/ext-base.js"&gt;&lt;/script&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;script type="text/javascript" src="&lt;%=BaseUrl%&gt;Javascript/ext/ext-all.js"&gt;&lt;/script&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;script type="text/javascript" src="&lt;%=BaseUrl%&gt;Javascript/ext/build/locale/ext-lang-zh_CN.js"&gt;&lt;/script&gt;<br />
&lt;%--&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;script type="text/javascript"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ext.util.CSS.swapStyleSheet("theme", "&lt;%=BaseUrl%&gt;App_Themes/slate/css/skin.css");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/script&gt;--%&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;form id="form1" runat="server"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;div&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;asp:ContentPlaceHolder id="ContentMainWorkSpace" runat="server"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/asp:ContentPlaceHolder&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/div&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/form&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</p>
<p>3。所有网页继承母版，后台类直接写C#方法即可，爱怎么写就怎么样。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ajax类的通信取代,如下代码</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Ajax.AjaxMethod(HttpSessionStateRequirement.ReadWrite)]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public bool UserCheck(string name,string pass)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (name.Equals("aa") &amp;&amp; pass.Equals("aa"))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Session["Uname"] = name;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Session["Upass"] = pass;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>4。前台JS-AJAX直接调用服务器方法</p>
<p>//现在只需直接调用类.方法，就行了，<font color="#ff0000">效率测试非常不错，页面无刷新，所见即所得，太爽了吧！！</font></p>
<p><font color="#ff0000">&nbsp;&nbsp;&nbsp; var login = function(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var c=Login.UserCheck(document.getElementById('Uname').value,document.getElementById('Upass').value);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(c.value==true)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert('通过');<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert('不通过');<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var ck=Login.SessionCheck();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(ck.value){alert('已登陆')}else{alert('未登陆');}</font></p>
<p><font color="#339966">//原来的EXT实现很麻烦，需要按下面的步骤来</font></p>
<p><font color="#339966">//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 执行当前表单面板的submit<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f.form.submit({<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 动作发生期间显示的文本信息<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; waitMsg : '正在登录......',<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // submit发生时指向的地址<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url : 'http://localhost:2020/Service1.asmx/UserLogin',<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 表单提交方式<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; method : 'POST',<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 数据验证通过时发生的动作<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; success : function(form, action){<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; window.location.href = 'index.htm';<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 反之......<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; failure : function(form, action){<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reset();<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (action.failureType == Ext.form.Action.SERVER_INVALID)<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ext.MessageBox.alert('警告', action.result.errors.msg);<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });</font></p>
<p><font color="#0000ff">EXT超完美整合终于完成了，只须3分钟你就能快速用Xtype画出界面（因为有代码提示和单步调试），只须3分钟你就能快速完成数据库增删查改的代码（因为微软C#帮我们做了太多），只须3分钟你就能把前台和后台联结起来（即是独立的UI-JS界面，又是独立的业务逻辑层），还有1分钟我们出去逗逗隔壁公司的小妹妹吧。</font></p>
<p>&nbsp;</p>
<p><font face="Verdana">http://hi.baidu.com/tmk_xj/blog/item/f73e1a101c1883f9c3ce79a1.html</font></p>
<img src ="http://www.cnblogs.com/9who/aggbug/1262279.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41817/" target="_blank">[新闻]Intel首次公开展示Nehalem架构迅驰3平台</a>]]></description></item><item><title>C#与OOP之 接口 </title><link>http://www.cnblogs.com/9who/archive/2008/08/05/1261285.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Tue, 05 Aug 2008 09:53:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/08/05/1261285.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1261285.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/08/05/1261285.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1261285.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1261285.html</trackback:ping><description><![CDATA[摘要: 接口(interface) 简单地说接口就是一种对行为的契约或者规范。比如我们一说到&#8220;笔&#8221;，那么我们就知道它一定可以用来&#8220;书写&#8221;，而不管它是铅笔还是水笔，不管它是用木制的还是塑料制的。这里的&#8220;笔&#8221;就相当于一个契约（接口），它描述了&#8220;书写&#8221;这样一个行为。只要这个对象是&#8220;笔&#8221;，那么它&nbsp;&nbsp;<a href='http://www.cnblogs.com/9who/archive/2008/08/05/1261285.html'>阅读全文</a><img src ="http://www.cnblogs.com/9who/aggbug/1261285.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41816/" target="_blank">[新闻]Pogo浏览器</a>]]></description></item><item><title>C#中面向对象的OOP概念</title><link>http://www.cnblogs.com/9who/archive/2008/08/05/1261245.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Tue, 05 Aug 2008 09:31:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/08/05/1261245.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1261245.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/08/05/1261245.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1261245.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1261245.html</trackback:ping><description><![CDATA[<p style="margin: 0cm 0cm 0pt 30.7pt; text-indent: -30.7pt"><strong><span style="font-size: 12pt">一、</span></strong><strong><span style="font-size: 12pt">C#</span></strong><strong><span style="font-size: 12pt">的对象和类</span></strong><span style="font-size: 12pt"><br />
</span><span style="color: blue">对象</span>是包含数据和操作的实体，它既定义数据元素，又定义可应用这些数据元素的操作。<br />
<span style="color: blue">类</span>是对一组具有相同属性和行为的对象的描述，类的内容称为类的成员。<br />
<strong>声明类的语法：</strong><br />
访问修饰符 class 类名<br />
{<br />
&nbsp;&nbsp;//类的主体<br />
}<br />
给类命名应使用帕斯卡命名法，确保类的名称是一个名词。<br />
类的主题包含<span style="color: blue">成员变量和<span style="color: blue">成员方法</span></span><br />
声明成员变量语法：<br />
访问修饰符 数据类型 成员变量名；<br />
<strong>编码惯例：</strong><br />
公共成员变量、受保护成员变量和内部成员变量应使用帕斯卡命名法。<br />
<span style="color: blue">如：</span><span style="color: blue">public string Name;</span><br />
私有成员变量应使用骆驼命名法，并以下划线开头。<br />
<span style="color: blue">如：</span><span style="color: blue">private string _name;</span><br />
创建类的实例或对象，用C#的net关键字。</p>
<p style="margin: 0cm 0cm 0pt 30.7pt; text-indent: -30.7pt"><strong><span style="font-size: 12pt">二、访问修饰符：</span></strong><br />
<strong>访问修饰符</strong><strong> &nbsp;&nbsp;&nbsp;&nbsp; </strong><strong>说明</strong><strong><br />
</strong>public&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;可被所属类的成员以及不属于类的成员访问<br />
internal&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;可被当前程序集访问<br />
protected&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;可被所属类或派生自所属类的类型访问<br />
private&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;仅所属类的成员才可以访问<br />
<span style="color: blue">如果对类不指定访问修饰符，则类的默认访问修饰符为</span><span style="color: blue">internal</span><span style="color: blue">，但是类成员的默认访问修饰符为</span><span style="color: blue">private</span></p>
<p style="margin: 0cm 0cm 0pt 30.7pt; text-indent: -30.7pt"><strong><span style="font-size: 12pt">三、构造函数和析构函数</span></strong><strong><span style="font-size: 12pt"><br />
</span></strong><strong>1</strong><strong>、什么是构造函数</strong><strong><br />
</strong>构造函数是类中的一中特殊方法，每次创建类的实例时都会调用此方法。<br />
构造函数一般用来自动初始化成员变量，但也可以根据需要执行其他的动作<br />
构造函数与类同名，不返回任何值<br />
<strong>2.</strong><strong>声明构造函数的语法：</strong><span style="color: blue"><br />
</span>访问修饰符 类名()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//构造函数的主体<br />
}<br />
<span style="color: blue">没有参数的构造函数为默认构造函数，这种构造函数不接受任何参数。</span><span style="color: blue"><br />
</span><span style="color: blue">如果类未定义默认构造函数，运行库将自动提供默认构造函数。</span><span style="color: blue"><br />
</span><strong>3.</strong><strong>带参数的构造函数</strong><strong><br />
</strong>访问修饰符 类名（参数）<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//构造函数的主体<br />
}<br />
<strong>4.</strong><strong>什么是析构函数</strong><br />
析构函数是C#的另一种特殊方法，用语执行清楚操作。析构函数不接受任何参数，也不带任何访问修饰符，析构函数主体包括的一些代码通常用于关闭有实例打开的数据库、文件或网络连接等。<br />
<span style="color: red">注意：</span><span style="color: red"><br />
</span><span style="color: red">一个类只能有一个析构函数。</span><span style="color: red"><br />
</span><span style="color: red">析构函数不能重载。</span><span style="color: red"><br />
</span><span style="color: red">析构函数不能显示或手动调用，只能有垃圾回收器自动调用。</span><span style="color: red"><br />
</span><span style="color: blue">语法：</span><span style="color: blue"><br />
</span>~类名()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//析构函数的主体<br />
}</p>
<p style="margin: 0cm 0cm 0pt 30.7pt; text-indent: -30.7pt"><strong><span style="font-size: 12pt">四、方法</span></strong><strong><span style="font-size: 12pt"><br />
</span></strong><strong>1</strong><strong>、声明方法</strong><strong><span style="font-size: 12pt"><br />
</span></strong>访问修饰符 返回值类型 方法名(参数)<strong><span style="font-size: 12pt"><br />
</span></strong>{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//方法主体<br />
}<strong><span style="font-size: 12pt"><br />
</span></strong><span style="color: red">注意：</span><span style="color: red"><br />
</span><span style="color: red">如果不返回任何值，则返回值类型为</span><span style="color: red">void</span><span style="color: red">，参数列表是由逗号分割的零个或多个变量声明列表，它是可选的。</span><span style="color: red"><br />
</span><span style="color: red">默认的访问修饰符为</span><span style="color: red">private<br />
</span><span style="color: blue">编码惯例：</span><span style="color: blue"><br />
</span><span style="color: blue">给成员方法命名应使用帕斯卡命名法，请确保方法的名称为动词或动词与对象组合。</span><span style="color: blue"><br />
</span><strong>2</strong><strong>、调用方法</strong><strong><br />
</strong>调用C#方法首先要创建对象实例，在用成员访问运算符点来调用方法<br />
<span style="color: blue">如：对象名</span><span style="color: blue">.</span><span style="color: blue">方法名</span><span style="color: blue">([</span><span style="color: blue">参数列表</span><span style="color: blue">]);</span><br />
在方法内使用<span style="color: blue">return [</span><span style="color: blue">表达式</span><span style="color: blue">]</span>语句用语将控制权交回调用程序。<br />
<strong>3.</strong><strong>方法重载</strong><br />
方法共用一个名称但对不同数据执行相似的功能，这种概念称为方法重载，不同的方法根据方法签名来识别，方法签名包括对方法的声明。每个重载方法的方法签名都应该是唯一的。<br />
<span style="color: blue">如下：</span><span style="color: blue"><br />
</span>&#8230;&#8230;<br />
Class Books<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void PayBill(int indix)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//方法主体<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void PayBill(string name)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//方法主体<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void PayBill(int indix,string name)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//方法主体<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<span style="color: blue"><br />
</span><span style="color: red">注意：</span><span style="color: red"><br />
</span><span style="color: red">可根据不同数量的参数来重载方法，每个被重载的方法都有不同的参数</span><span style="color: red"><br />
</span><span style="color: red">可根据不同类型的参数来重载方法，参数的数量保持不变。</span><span style="color: red"><br />
</span><strong>4</strong><strong>、静态方法</strong><strong><br />
</strong>静态方法就是一个类的所有实例共享的方法<br />
<span style="color: blue">语法：</span><br />
访问修饰符 static 返回值类型 方法名(参数列表)<br />
<span style="color: blue">说明：</span><br />
访问静态方法的时候不需要创建类的实例，采取&#8220;类名.方法名&#8221;即可，Console.Write()就是Console类的一个静态方法。</p>
<p style="margin: 0cm 0cm 0pt 30.7pt; text-indent: -30.7pt"><strong><span style="font-size: 12pt">五、命名空间</span></strong><strong><span style="font-size: 12pt"><br />
</span></strong>命名空间是为了避免名称冲突和有助于组织代码，在代码中使用命名空间将降低在其他应用程序中重用此代码的复杂性。命名空间相当于规定了不同的范围，在不同的范围内允许有相同的名称，用命名空间方式处理名称冲突的问题，使程序更简洁&#8216;更有条件和更有结构性。<br />
<span style="color: blue">语法：</span><br />
namespace 命名空间的名称<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//该命名空间的所有类都放在这里。<br />
}<br />
<span style="color: blue">编码惯例：</span><br />
给命名空间命名应使用帕斯卡命名法。</p>
<img src ="http://www.cnblogs.com/9who/aggbug/1261245.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41816/" target="_blank">[新闻]Pogo浏览器</a>]]></description></item><item><title>ASP.NET常用到的js通用函数 c#代码可以做成dll来使用</title><link>http://www.cnblogs.com/9who/archive/2008/08/05/1261007.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Tue, 05 Aug 2008 07:23:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/08/05/1261007.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1261007.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/08/05/1261007.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1261007.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1261007.html</trackback:ping><description><![CDATA[摘要: using System.Web;using System.Web.UI;using System.Text;public abstract class JS { /**//// &lt;summary&gt; /// 客户端打开窗口 /// &lt;/summary&gt; /// &lt;param name="strUrl"&gt;&lt;/param&gt; public static v&nbsp;&nbsp;<a href='http://www.cnblogs.com/9who/archive/2008/08/05/1261007.html'>阅读全文</a><img src ="http://www.cnblogs.com/9who/aggbug/1261007.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41816/" target="_blank">[新闻]Pogo浏览器</a>]]></description></item><item><title>ASP.NET 脚本侵入概述</title><link>http://www.cnblogs.com/9who/archive/2008/08/05/1260767.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Tue, 05 Aug 2008 03:21:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/08/05/1260767.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1260767.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/08/05/1260767.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1260767.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1260767.html</trackback:ping><description><![CDATA[<div class="introduction">
<p>&nbsp;&nbsp;&nbsp;&nbsp; 从浏览器的角度来看，网页只是一个长字符串。浏览器会按顺序处理这个字符串，在此过程中，会显示某些字符，同时按特殊规则解释其他字符（如 <span class="code">&lt;b&gt;</span> 和 <span class="code">&lt;script&gt;</span>）。如果恶意用户可以将某些特殊字符插入到页中，则浏览器将不知道这些字符不应该处于该位置，将作为页的一部分处理它们。</p>
<p>一个简单化的脚本利用的工作方式如下所示。如果应用程序允许用户发布对最新影片的评论以供其他用户阅读，则利用脚本的步骤可以是：</p>
<ol>
    <li>
    <p>应用程序显示一个用户可以输入评论的窗体。恶意用户编写了一个其中包含 <span class="code">&lt;script&gt;</span> 块的评论。</p>
    </li>
    <li>
    <p>发送窗体，恶意用户的评论将存储在数据库中。</p>
    </li>
    <li>
    <p>另一用户访问该站点。在构造页时，应用程序会从数据库中读取评论并将它们放在页中。恶意用户的 <span class="code">&lt;script&gt;</span> 块将写入页中，就好像它是文本评论一样。</p>
    </li>
    <li>
    <p>当第二个用户的浏览器显示此页时，它将遇到 &lt;<span class="code">script&gt;</span> 块并执行它。</p>
    </li>
</ol>
<p>恶意用户还可以使用其他方法来利用脚本。大多数脚本利用都会要求应用程序接受恶意输入，并将其插入到页中（或回显它），浏览器将在该页中执行它。这种利用带来的潜在损害取决于所执行的脚本。它可以是无足轻重的，如在浏览器中弹出的烦人的消息。但是，它也可能会窃取 Cookie、窃取用户输入（如密码），甚至在用户的计算机上运行本机代码（如果对 Internet 安全性的要求不严格），从而造成严重的损害。</p>
<p>有关防止脚本利用的信息，请参见<a href="http://www.cnblogs.com/9who/admin/ms-help://MS.MSDNQTR.v90.chs/dv_vwdcon/html/6f67973f-dda0-45a1-ba9d-e88532d7dc5b.htm">如何：通过对字符串应用 HTML 编码在 Web 应用程序中防止脚本侵入</a>。</p>
</div>
<h1 class="heading"><span onkeypress="ExpandCollapse_CheckKey(sectionToggle0, event)" style="cursor: default" onclick="ExpandCollapse(sectionToggle0)" tabindex="0">SQL 语句利用</span></h1>
<div class="section" id="sectionSection0" name="collapseableSection">
<p>有一种脚本利用的变体可以导致恶意 SQL 语句的执行。如果应用程序提示用户输入信息并将用户的输入串联为表示 SQL 语句的字符串，则会出现这种情况。例如，应用程序可能提示输入客户姓名，目的是为了执行类似如下的语句：</p>
<div class="code"><span codelanguage="other">
<table cellspacing="0" cellpadding="0" width="100%">
    <tr>
            <th>&nbsp;</th>
            <th><span class="copyCode" onkeypress="CopyCode_CheckKey(this, event)" onmouseover="ChangeCopyCodeIcon(this)" onclick="CopyCode(this)" tabindex="0" onmouseout="ChangeCopyCodeIcon(this)">复制代码</span></th>
        </tr>
        <tr>
            <td colspan="2">
            <pre>"Select * From Customers where CustomerName = " &amp; txtCustomerName.Value</pre>
            </td>
        </tr>
    </table>
</span></div>
<p>但是，对数据库有所了解的恶意用户可能使用文本框输入包含客户姓名的嵌入式 SQL 语句，产生类似如下的语句：</p>
<div class="code"><span codelanguage="other">
<table cellspacing="0" cellpadding="0" width="100%">
    <tr>
            <th>&nbsp;</th>
            <th><span class="copyCode" onkeypress="CopyCode_CheckKey(this, event)" onmouseover="ChangeCopyCodeIcon(this)" onclick="CopyCode(this)" tabindex="0" onmouseout="ChangeCopyCodeIcon(this)">复制代码</span></th>
        </tr>
        <tr>
            <td colspan="2">
            <pre>Select * From Customers Where CustomerName = <codefeaturedelement xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">'a' Delete From </codefeaturedelement>
            <codefeaturedelement xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">Customers Where CustomerName &gt; ''</codefeaturedelement></pre>
            </td>
        </tr>
    </table>
</span></div>
<p>执行该查询时，就会危害数据库。</p>
</div>
<h1 class="heading"><span onkeypress="ExpandCollapse_CheckKey(sectionToggle1, event)" style="cursor: default" onclick="ExpandCollapse(sectionToggle1)" tabindex="0">防止脚本利用</span></h1>
<div class="section" id="sectionSection1" name="collapseableSection">
<p>防止脚本利用的主要方法就是决不信任来自用户的信息。假定从浏览器发送到您的应用程序的任何数据都包含恶意脚本。</p>
<p>同样，每次将字符串写入页时，您都应该假定字符串可能包含恶意脚本（除非您自己以编程方式创建了字符串）。例如，在从数据库中读取字符串时，您应该假定它们可能包含恶意脚本。安全意识很强的开发人员甚至不信任他们自己的数据库，理由是他们认为恶意用户可能有办法篡改数据库。</p>
<p>ASP.NET 为您提供了几种有助于防止脚本利用的方法：</p>
<ul>
    <li>
    <p>ASP.NET 对查询字符串、窗体变量和 Cookie 值执行请求验证。默认情况下，如果当前的 <mshelp:link tabindex="0" keywords="P:System.Web.HttpContext.Request">Request</mshelp:link> 包含 HTML 编码的元素或某些 HTML 字符（如表示长破折号的 <span class="code">&#151;</span>），则 ASP.NET 页框架将引发一个错误。</p>
    </li>
    <li>
    <p>如果要在应用程序中显示字符串，但不信任这些字符串，可以在响应中回写字符串时将 HTML 编码应用于这些字符串。例如，进行编码后，标记 <span class="code">&lt;b&gt;</span> 将变成 <span class="code">&amp;lt;b&amp;gt;</span>。如果您要显示的字符串来自您尚未确定信任其内容的数据库时，您可能会这样做。</p>
    </li>
    <li>
    <p>如果希望应用程序接受某个 HTML（例如，来自用户的某些格式设置说明），那么，在将这个 HTML 提交给服务器之前，应在客户端对其进行编码。</p>
    </li>
    <li>
    <p>为了防止 SQL 语句利用，决不能串联字符串创建 SQL 查询。相反，使用参数化查询并将用户输入分配给参数对象。有关详细信息，请参见<mshelp:link tabindex="0" keywords="195e0209-68d4-4e86-8a3b-f0d2f14332d8">数据适配器命令中的参数</mshelp:link>。</p>
    </li>
    <li>
    <p>始终对一组预期值执行窗体输入验证以及字符串格式设置/类型验证。例如，如果特定的窗体变量应为整数，则使用 <mshelp:link tabindex="0" keywords="Overload:System.Int32.TryParse">Int32<span class="languageSpecificText"><span class="cs">.</span><span class="vb">.</span><span class="cpp">::</span><span class="nu">.</span></span>TryParse</mshelp:link> 方法验证该值是否确实为整数，并使用范围检查帮助确保该值位于可接受范围内。</p>
    </li>
</ul>
</div>
<img src ="http://www.cnblogs.com/9who/aggbug/1260767.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41816/" target="_blank">[新闻]Pogo浏览器</a>]]></description></item><item><title>总结自己近两年来的.NET的学习经历</title><link>http://www.cnblogs.com/9who/archive/2008/08/01/1258248.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Fri, 01 Aug 2008 07:57:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/08/01/1258248.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1258248.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/08/01/1258248.html#Feedback</comments><slash:comments>17</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1258248.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1258248.html</trackback:ping><description><![CDATA[摘要:      2006年低开始接触asp.net ，那时才上大三就已经参加工作了，单位做个站要求用.net 的，那时比较盛行asp ，说真的当时你把asp用的很熟练就不错了，在这之前，我做过个人小站，都是照搬人家的asp程序，可以说手写代码自己很不熟悉，记忆中比较常用的就是asp中的五个内置对象，基本做什么都用到他，那时一直都是靠手工输入代码，效率也是非常低。（附asp.net 常用类库列表）&nbsp;&nbsp;<a href='http://www.cnblogs.com/9who/archive/2008/08/01/1258248.html'>阅读全文</a><img src ="http://www.cnblogs.com/9who/aggbug/1258248.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41807/" target="_blank">[新闻]洪磊口述:番茄花园如何捆绑流氓软件月入十万</a>]]></description></item><item><title>最简单的C#快速入门</title><link>http://www.cnblogs.com/9who/archive/2008/07/30/1256602.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Wed, 30 Jul 2008 08:40:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/07/30/1256602.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1256602.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/07/30/1256602.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1256602.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1256602.html</trackback:ping><description><![CDATA[摘要: 在一小时内学会 C#。使用例程，简单却完整的探索 C# 语言的构造和特点。本文特别适合有 C++ 基础却没有太多精力学习 C# 的读者。关于作者Aisha Ikram我现在在英国一家软件公司任技术带头人。我是计算机科学的硕士。我主要使用 .NET 1.1/2.0, C#, VB.NET, ASP.NET, VC++ 6, MFC, ATL, COM/DCOM, SQL Server 2000/20&nbsp;&nbsp;<a href='http://www.cnblogs.com/9who/archive/2008/07/30/1256602.html'>阅读全文</a><img src ="http://www.cnblogs.com/9who/aggbug/1256602.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41813/" target="_blank">[新闻]2008年8月21日IT博客精选：盖茨复出？</a>]]></description></item><item><title>一个C#睡觉前的夜晚</title><link>http://www.cnblogs.com/9who/archive/2008/07/29/1255999.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Tue, 29 Jul 2008 15:13:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/07/29/1255999.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1255999.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/07/29/1255999.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1255999.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1255999.html</trackback:ping><description><![CDATA[<p><font face="Verdana">从前，在南方一块奇异的土地上，有个工人名叫彼得，他非常勤奋，对他的老板总是百依百顺。但是他的老板是个吝啬的人，从不信任别人，坚决要求随时知道彼得的工作进度，以防止他偷懒。但是彼得又不想让老板呆在他的办公室里站在背后盯着他，于是就对老板做出承诺：无论何时，只要我的工作取得了一点进展我都会及时让你知道。彼得通过周期性地使用&#8220;带类型的引用&#8221;(原文为：&#8220;typed reference&#8221; 也就是delegate？？)&#8220;回调&#8221;他的老板来实现他的承诺，如下：</font></p>
<font face="Verdana">
<p><br />
class Worker {<br />
&nbsp;&nbsp;&nbsp; public void Advise(Boss boss) { _boss = boss; }<br />
&nbsp;&nbsp;&nbsp; public void DoWork() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;工作: 工作开始&#8221;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( _boss != null ) _boss.WorkStarted();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;工作: 工作进行中&#8221;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( _boss != null ) _boss.WorkProgressing();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("&#8220;工作: 工作完成&#8221;");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( _boss != null ) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int grade = _boss.WorkCompleted();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;工人的工作得分＝&#8221; + grade);<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
private Boss _boss;<br />
}</p>
<p>class Boss {<br />
&nbsp;&nbsp;&nbsp; public void WorkStarted() { /* 老板不关心。 */ }<br />
&nbsp;&nbsp;&nbsp; public void WorkProgressing() { /*老板不关心。 */ }<br />
&nbsp;&nbsp;&nbsp; public int WorkCompleted() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;时间差不多！&#8221;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 2; /* 总分为10 */<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p>class Universe {<br />
&nbsp;&nbsp;&nbsp; static void Main() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Worker peter = new Worker();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boss boss = new Boss();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; peter.Advise(boss);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; peter.DoWork();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;Main: 工人工作完成&#8221;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.ReadLine();<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p>&nbsp;</p>
<p>接口</p>
<p>现在，彼得成了一个特殊的人，他不但能容忍吝啬的老板，而且和他周围的宇宙也有了密切的联系，以至于他认为宇宙对他的工作进度也感兴趣。不幸的是，他必须也给宇宙添加一个特殊的回调函数Advise来实现同时向他老板和宇宙报告工作进度。彼得想要把潜在的通知的列表和这些通知的实现方法分离开来，于是他决定把方法分离为一个接口：</p>
<p>&nbsp;</p>
<p>interface IWorkerEvents {<br />
&nbsp;&nbsp;&nbsp; void WorkStarted();<br />
&nbsp;&nbsp;&nbsp; void WorkProgressing();<br />
&nbsp;&nbsp;&nbsp; int WorkCompleted();<br />
}</p>
<p>class Worker {<br />
&nbsp;&nbsp;&nbsp; public void Advise(IWorkerEvents events) { _events = events; }<br />
&nbsp;&nbsp;&nbsp; public void DoWork() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;工作: 工作开始&#8221;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( _events != null ) _events.WorkStarted();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;工作: 工作进行中&#8221;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(_events != null ) _events.WorkProgressing();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("&#8220;工作: 工作完成&#8221;");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(_events != null ) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int grade = _events.WorkCompleted();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;工人的工作得分＝&#8221; + grade);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; private IWorkerEvents _events;<br />
}</p>
<p>class Boss : IWorkerEvents {<br />
&nbsp;&nbsp;&nbsp; public void WorkStarted() { /* 老板不关心。 */ }<br />
&nbsp;&nbsp;&nbsp; public void WorkProgressing() { /* 老板不关心。 */ }<br />
&nbsp;&nbsp;&nbsp; public int WorkCompleted() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;时间差不多！&#8221;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 3; /* 总分为10 */<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p>&nbsp;</p>
<p>委托</p>
<p>不幸的是，每当彼得忙于通过接口的实现和老板交流时，就没有机会及时通知宇宙了。至少他应该忽略身在远方的老板的引用，好让其他实现了IWorkerEvents的对象得到他的工作报告。（&#8221;At least he'd abstracted the reference of his boss far away from him so that others who implemented the IWorkerEvents interface could be notified of his work progress&#8221; 原话如此，不理解到底是什么意思 ）</p>
<p>他的老板还是抱怨得很厉害。&#8220;彼得！&#8221;他老板吼道，&#8220;你为什么在工作一开始和工作进行中都来烦我？！我不关心这些事件。你不但强迫我实现了这些方法，而且还在浪费我宝贵的工作时间来处理你的事件，特别是当我外出的时候更是如此！你能不能不再来烦我？&#8221;</p>
<p>于是，彼得意识到接口虽然在很多情况都很有用，但是当用作事件时，&#8220;粒度&#8221;不够好。他希望能够仅在别人想要时才通知他们，于是他决定把接口的方法分离为单独的委托，每个委托都像一个小的接口方法：</p>
<p>&nbsp;</p>
<p>delegate void WorkStarted();<br />
delegate void WorkProgressing();<br />
delegate int WorkCompleted();</p>
<p>class Worker {<br />
&nbsp;&nbsp;&nbsp; public void DoWork() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;工作: 工作开始&#8221;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( started != null ) started();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;工作: 工作进行中&#8221;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( progressing != null ) progressing();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("&#8220;工作: 工作完成&#8221;");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( completed != null ) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int grade = completed();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;工人的工作得分＝&#8221; + grade);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public WorkStarted started;<br />
&nbsp;&nbsp;&nbsp; public WorkProgressing progressing;<br />
&nbsp;&nbsp;&nbsp; public WorkCompleted completed;<br />
}</p>
<p>class Boss {<br />
&nbsp;&nbsp;&nbsp; public int WorkCompleted() {<br />
&nbsp;&nbsp;&nbsp; Console.WriteLine("Better");<br />
&nbsp;&nbsp;&nbsp; return 4; /* 总分为10 */<br />
}<br />
}</p>
<p>class Universe {<br />
&nbsp;&nbsp;&nbsp; static void Main() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Worker peter = new Worker();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boss boss = new Boss();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; peter.completed = new WorkCompleted(boss.WorkCompleted);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; peter.DoWork();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;Main: 工人工作完成&#8221;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.ReadLine();<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p>&nbsp;</p>
<p>静态监听者</p>
<p>这样，彼得不会再拿他老板不想要的事件来烦他老板了，但是他还没有把宇宙放到他的监听者列表中。因为宇宙是个包涵一切的实体，看来不适合使用实例方法的委托（想像一下，实例化一个&#8220;宇宙&#8221;要花费多少资源&#8230;..），于是彼得就需要能够对静态委托进行挂钩，委托对这一点支持得很好：</p>
<p>&nbsp;</p>
<p>class Universe {<br />
&nbsp;&nbsp;&nbsp; static void WorkerStartedWork() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("Universe notices worker starting work");<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; static int WorkerCompletedWork() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("Universe pleased with worker's work");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 7;<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; static void Main() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Worker peter = new Worker();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boss boss = new Boss();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; peter.completed = new WorkCompleted(boss.WorkCompleted);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; peter.started = new WorkStarted(Universe.WorkerStartedWork);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; peter.completed = new WorkCompleted(Universe.WorkerCompletedWork);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; peter.DoWork();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;Main: 工人工作完成&#8221;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.ReadLine();<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p>&nbsp;</p>
<p>事件</p>
<p>不幸的是，宇宙太忙了，也不习惯时刻关注它里面的个体，它可以用自己的委托替换了彼得老板的委托。这是把彼得的Worker类的的委托字段做成public的一个无意识的副作用。同样，如果彼得的老板不耐烦了，也可以决定自己来激发彼得的委托（真是一个粗鲁的老板）：</p>
<p>// Peter's boss taking matters into his own hands<br />
if( peter.completed != null ) peter.completed();<br />
彼得不想让这些事发生，他意识到需要给每个委托提供&#8220;注册&#8221;和&#8220;反注册&#8221;功能，这样监听者就可以自己添加和移除委托，但同时又不能清空整个列表也不能随意激发彼得的事件了。彼得并没有来自己实现这些功能，相反，他使用了event关键字让C#编译器为他构建这些方法：</p>
<p>&nbsp;</p>
<p>class Worker {</p>
<p>&nbsp;&nbsp;&nbsp; public event WorkStarted started;<br />
&nbsp;&nbsp;&nbsp; public event WorkProgressing progressing;<br />
&nbsp;&nbsp;&nbsp; public event WorkCompleted completed;<br />
}</p>
<p>&nbsp;</p>
<p>彼得知道event关键字在委托的外边包装了一个property，仅让C#客户通过+= 和 -=操作符来添加和移除，强迫他的老板和宇宙正确地使用事件。</p>
<p>&nbsp;</p>
<p>static void Main() {<br />
&nbsp;&nbsp;&nbsp; Worker peter = new Worker();<br />
&nbsp;&nbsp;&nbsp; Boss boss = new Boss();<br />
&nbsp;&nbsp;&nbsp; peter.completed += new WorkCompleted(boss.WorkCompleted);<br />
&nbsp;&nbsp;&nbsp; peter.started += new WorkStarted(Universe.WorkerStartedWork);<br />
&nbsp;&nbsp;&nbsp; peter.completed += new WorkCompleted(Universe.WorkerCompletedWork);<br />
&nbsp;&nbsp;&nbsp; peter.DoWork();</p>
<p>&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;Main: 工人工作完成&#8221;);<br />
&nbsp;&nbsp;&nbsp; Console.ReadLine();<br />
}</p>
<p>&nbsp;</p>
<p>&#8220;收获&#8221;所有结果</p>
<p>到这时，彼得终于可以送一口气了，他成功地满足了所有监听者的需求，同时避免了与特定实现的紧耦合。但是他注意到他的老板和宇宙都为它的工作打了分，但是他仅仅接收了一个分数。面对多个监听者，他想要&#8220;收获&#8221;所有的结果，于是他深入到代理里面，轮询监听者列表，手工一个个调用：</p>
<p>&nbsp;</p>
<p>public void DoWork() {<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; Console.WriteLine("&#8220;工作: 工作完成&#8221;");<br />
&nbsp;&nbsp;&nbsp; if( completed != null ) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach( WorkCompleted wc in completed.GetInvocationList() ) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int grade = wc();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;工人的工作得分＝&#8221; + grade);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p>异步通知：激发 &amp; 忘掉</p>
<p>同时，他的老板和宇宙还要忙于处理其他事情，也就是说他们给彼得打分所花费的事件变得非常长：</p>
<p>&nbsp;</p>
<p>class Boss {<br />
&nbsp;&nbsp;&nbsp; public int WorkCompleted() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Threading.Thread.Sleep(3000);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("Better"); return 6; /* 总分为10 */<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
<p>class Universe {<br />
&nbsp;&nbsp;&nbsp; static int WorkerCompletedWork() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Threading.Thread.Sleep(4000);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("Universe is pleased with worker's work");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 7;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
}</p>
<p><br />
很不幸，彼得每次通知一个监听者后必须等待它给自己打分，现在这些通知花费了他太多的工作事件。于是他决定忘掉分数，仅仅异步激发事件：</p>
<p>&nbsp;</p>
<p>public void DoWork() {<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; Console.WriteLine("&#8220;工作: 工作完成&#8221;");<br />
&nbsp;&nbsp;&nbsp; if( completed != null ) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach( WorkCompleted wc in completed.GetInvocationList() )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wc.BeginInvoke(null, null);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
&nbsp;</p>
<p><br />
异步通知：轮询</p>
<p>这使得彼得可以通知他的监听者，然后立即返回工作，让进程的线程池来调用这些代理。随着时间的过去，彼得发现他丢失了他工作的反馈，他知道听取别人的赞扬和努力工作一样重要，于是他异步激发事件，但是周期性地轮询，取得可用的分数。</p>
<p>&nbsp;</p>
<p>public void DoWork() {<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; Console.WriteLine("&#8220;工作: 工作完成&#8221;");<br />
&nbsp;&nbsp;&nbsp; if( completed != null ) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach( WorkCompleted wc in completed.GetInvocationList() ) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IAsyncResult res = wc.BeginInvoke(null, null);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while( !res.IsCompleted ) System.Threading.Thread.Sleep(1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int grade = wc.EndInvoke(res);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;工人的工作得分＝&#8221; + grade);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
&nbsp;</p>
<p><br />
异步通知：委托</p>
<p>不幸地，彼得有回到了一开始就想避免的情况中来，比如，老板站在背后盯着他工作。于是，他决定使用自己的委托作为他调用的异步委托完成的通知，让他自己立即回到工作，但是仍可以在别人给他的工作打分后得到通知：</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; public void DoWork() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("&#8220;工作: 工作完成&#8221;");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( completed != null ) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach( WorkCompleted wc in completed.GetInvocationList() ) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wc.BeginInvoke(new AsyncCallback(WorkGraded), wc);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; private void WorkGraded(IAsyncResult res) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WorkCompleted wc = (WorkCompleted)res.AsyncState;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int grade = wc.EndInvoke(res);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(&#8220;工人的工作得分＝&#8221; + grade);<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;</p>
<p><br />
宇宙中的幸福</p>
<p>彼得、他的老板和宇宙最终都满足了。彼得的老板和宇宙可以收到他们感兴趣的事件通知，减少了实现的负担和非必需的往返&#8220;差旅费&#8221;。彼得可以通知他们，而不管他们要花多长时间来从目的方法中返回，同时又可以异步地得到他的结果。彼得知道，这并不*十分*简单，因为当他异步激发事件时，方法要在另外一个线程中执行，彼得的目的方法完成的通知也是一样的道理。但是，迈克和彼得是好朋友，他很熟悉线程的事情，可以在这个领域提供指导。</p>
<p>&nbsp;</p>
<p>他们永远幸福地生活下去&#8230;&#8230;&lt;完&gt;<br />
</font></p>
<img src ="http://www.cnblogs.com/9who/aggbug/1255999.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41812/" target="_blank">[新闻]微软宣布将斥资1亿美元购买Novell证书</a>]]></description></item><item><title>学习.NET 到底学习什么</title><link>http://www.cnblogs.com/9who/archive/2008/07/29/1255455.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Tue, 29 Jul 2008 04:04:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/07/29/1255455.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1255455.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/07/29/1255455.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1255455.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1255455.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 还有10分钟就要下班了，趁这点时间给大家写一篇文章，学习.net到底学习什么，偶也是学习.net 有一段时间的人了，和大部分人一样，偶也是自学，可以现在学习.net 开发的人员很多都是自学的，特别新工具的使用，哪有学校的更新速度都没有这么快，想问 在下的各位，有谁在学校里学过vs2008呢，在做.net 开发的道路，自学是很重要的一部分，没有了教师的直到，在.net 中 迷茫，一会出来了&nbsp;ajax 一会出来个Linq ，一会又出来了<a href="?catid=147444">Silverlight</a>， 让人感觉很浮躁，切忌这只是噩梦的开始，更多的是如何运用这些东西，把这些新的特征正确的运用到实际开发中去，听所 Linq 操作数据库 刚刚地，偶也跟着开始Linq之旅 ，好用是好，看到别人用得饿，感觉代码确实又少了，相对与dataview操作database，但是真正在做项目的时候，却又感到无从下手，就好像感觉不是属于自己的该应用到的东东，迷茫中，使用ajax开发的项目的界面效果，那是刚刚地，最近偶采用了extjs+.net 做的一个oa 项目，看到绚丽的效果 ，却又不知道怎么与数据库打交道，慢慢的google，发现要学习的东西真的不少，但是做为一个写code时间不长的人，如何才能更好的学习.net 的呢，应用.net 的新特征。好了，下班了，回头在写吧
<img src ="http://www.cnblogs.com/9who/aggbug/1255455.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41812/" target="_blank">[新闻]微软宣布将斥资1亿美元购买Novell证书</a>]]></description></item><item><title>c#时间格式化字符串详解 长短转化</title><link>http://www.cnblogs.com/9who/archive/2008/07/29/1255437.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Tue, 29 Jul 2008 03:42:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/07/29/1255437.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1255437.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/07/29/1255437.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1255437.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1255437.html</trackback:ping><description><![CDATA[<span style="padding-left: 25px; font-size: 14px; line-height: 180%">有时候我们要对时间进行转换,达到不同的显示效果<br />
　默认格式为:2005-6-6 14:33:34<br />
　如果要换成成200506,06-2005,2005-6-6或更多的该怎么办呢<br />
　我们要用到:DateTime.ToString的方法(String, IFormatProvider)<br />
　<br />
　using System;<br />
　using System.Globalization;<br />
　String format="D";<br />
　DateTime date=DataTime,Now;<br />
　Response.Write(date.ToString(format, DateTimeFormatInfo.InvariantInfo));<br />
　结果输出<br />
　Thursday, June 16, 2005<br />
　<br />
　参数format格式详细用法<br />
　格式字符 关联属性/说明<br />
　d ShortDatePattern -----08/30/2006<br />
　D LongDatePattern -----Wednesday, 30 August 2006<br />
　f 完整日期和时间（长日期和短时间） -----Wednesday, 30 August 2006 23:21<br />
　F FullDateTimePattern（长日期和长时间） -----Wednesday, 30 August 2006 23:22:02<br />
　g 常规（短日期和短时间） -----08/30/2006 23:22<br />
　G 常规（短日期和长时间） -----08/30/2006 23:23:11<br />
　m、M MonthDayPattern<br />
　r、R RFC1123Pattern<br />
　s 使用当地时间的 SortableDateTimePattern（基于 ISO 8601）<br />
　t ShortTimePattern ------23:24<br />
　T LongTimePattern -------23:24:30<br />
　u UniversalSortableDateTimePattern 用于显示通用时间的格式 -------2006-08-30 23:25:10Z<br />
　U 使用通用时间的完整日期和时间（长日期和长时间） -----Wednesday, 30 August 2006 15:25:37<br />
　y、Y YearMonthPattern<br />
　<br />
　下表列出了可被合并以构造自定义模式的模式。这些模式是区分大小写的；例如，识别&#8220;MM&#8221;，但不识别&#8220;mm&#8221;。如果自定义模式包含空白字符或用单引号括起来的字符，则输出字符串页也将包含这些字符。未定义为格式模式的一部分或未定义为格式字符的字符按其原义复制。<br />
　<br />
　格式模式 说明<br />
　d 月中的某一天。一位数的日期没有前导零。<br />
　dd 月中的某一天。一位数的日期有一个前导零。<br />
　ddd 周中某天的缩写名称，在 AbbreviatedDayNames 中定义。<br />
　dddd 周中某天的完整名称，在 DayNames 中定义。<br />
　M 月份数字。一位数的月份没有前导零。<br />
　MM 月份数字。一位数的月份有一个前导零。<br />
　MMM 月份的缩写名称，在 AbbreviatedMonthNames 中定义。<br />
　MMMM 月份的完整名称，在 MonthNames 中定义。<br />
　y 不包含纪元的年份。如果不包含纪元的年份小于 10，则显示不具有前导零的年份。<br />
　yy 不包含纪元的年份。如果不包含纪元的年份小于 10，则显示具有前导零的年份。<br />
　yyyy 包括纪元的四位数的年份。<br />
　gg 时期或纪元。如果要设置格式的日期不具有关联的时期或纪元字符串，则忽略该模式。<br />
　h 12 小时制的小时。一位数的小时数没有前导零。<br />
　hh 12 小时制的小时。一位数的小时数有前导零。<br />
　H 24 小时制的小时。一位数的小时数没有前导零。<br />
　HH 24 小时制的小时。一位数的小时数有前导零。<br />
　m 分钟。一位数的分钟数没有前导零。<br />
　mm 分钟。一位数的分钟数有一个前导零。<br />
　s 秒。一位数的秒数没有前导零。<br />
　ss 秒。一位数的秒数有一个前导零。<br />
　f 秒的小数精度为一位。其余数字被截断。<br />
　ff 秒的小数精度为两位。其余数字被截断。<br />
　fff 秒的小数精度为三位。其余数字被截断。<br />
　ffff 秒的小数精度为四位。其余数字被截断。<br />
　fffff 秒的小数精度为五位。其余数字被截断。<br />
　ffffff 秒的小数精度为六位。其余数字被截断。<br />
　fffffff 秒的小数精度为七位。其余数字被截断。<br />
　t 在 AMDesignator 或 PMDesignator 中定义的 AM/PM 指示项的第一个字符（如果存在）。<br />
　tt 在 AMDesignator 或 PMDesignator 中定义的 AM/PM 指示项（如果存在）。<br />
　z 时区偏移量（&#8220;+&#8221;或&#8220;-&#8221;后面仅跟小时）。一位数的小时数没有前导零。例如，太平洋标准时间是&#8220;-8&#8221;。<br />
　zz 时区偏移量（&#8220;+&#8221;或&#8220;-&#8221;后面仅跟小时）。一位数的小时数有前导零。例如，太平洋标准时间是&#8220;-08&#8221;。<br />
　zzz 完整时区偏移量（&#8220;+&#8221;或&#8220;-&#8221;后面跟有小时和分钟）。一位数的小时数和分钟数有前导零。例如，太平洋标准时间是&#8220;-08:00&#8221;。<br />
　: 在 TimeSeparator 中定义的默认时间分隔符。<br />
　/ 在 DateSeparator 中定义的默认日期分隔符。<br />
　% c 其中 c 是格式模式（如果单独使用）。如果格式模式与原义字符或其他格式模式合并，则可以省略&#8220;%&#8221;字符。<br />
　\ c 其中 c 是任意字符。照原义显示字符。若要显示反斜杠字符，请使用&#8220;\\&#8221;。<br />
　<br />
　只有上面第二个表中列出的格式模式才能用于创建自定义模式；在第一个表中列出的标准格式字符不能用于创建自定义模式。自定义模式的长度至少为两个字符；例如，<br />
　<br />
　DateTime.ToString( "d") 返回 DateTime 值；&#8220;d&#8221;是标准短日期模式。<br />
　DateTime.ToString( "%d") 返回月中的某天；&#8220;%d&#8221;是自定义模式。<br />
　DateTime.ToString( "d ") 返回后面跟有一个空白字符的月中的某天；&#8220;d&#8221;是自定义模式。<br />
　<br />
　比较方便的是,上面的参数可以随意组合,并且不会出错,多试试,肯定会找到你要的时间格式<br />
　如要得到2005年06月 这样格式的时间<br />
　可以这样写:<br />
　date.ToString("yyyy年MM月", DateTimeFormatInfo.InvariantInfo)<br />
　如此类推<br />
<br />
date.ToString("yyyy/MM/dd HH:mm:ss", DateTimeFormatInfo.InvariantInfo)</span>
<img src ="http://www.cnblogs.com/9who/aggbug/1255437.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/41812/" target="_blank">[新闻]微软宣布将斥资1亿美元购买Novell证书</a>]]></description></item><item><title>利用GridView控件的HyperLinkField连接数据行</title><link>http://www.cnblogs.com/9who/archive/2008/07/29/1255315.html</link><dc:creator>9who</dc:creator><author>9who</author><pubDate>Tue, 29 Jul 2008 02:11:00 GMT</pubDate><guid>http://www.cnblogs.com/9who/archive/2008/07/29/1255315.html</guid><wfw:comment>http://www.cnblogs.com/9who/comments/1255315.html</wfw:comment><comments>http://www.cnblogs.com/9who/archive/2008/07/29/1255315.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/9who/comments/commentRss/1255315.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/9who/services/trackbacks/1255315.html</trackback:ping><description><![CDATA[<div style="margin: 3pt 0cm"><span style="font-family: 宋体">借助于</span><strong>GridView</strong><span style="font-family: 宋体">控件的</span><strong>HyperLinkField</strong><span style="font-family: 宋体">数据行，我们便可以在</span><strong>GridView</strong><span style="font-family: 宋体">控件中替每一笔数据列显示出一个超级链接，并让用户轻易重新导向至特定的目标位置（特定网页或网页中的位置）。</span></div>
<div style="margin: 3pt 0cm">&nbsp;</div>
<div style="margin: 3pt 0cm"><span style="font-family: 宋体">在使用</span><strong>HyperLinkField</strong><span style="font-family: 宋体">数据行时，首先要考虑的就是超级链接上的文字。关于此点，可分为下列两种状况来说明：</span></div>
<div style="margin: 3pt 0cm">&nbsp;</div>
<div style="margin: 3pt 0cm 3pt 24pt; text-indent: -24pt"><span style="font-family: wingdings">q<span Times New Roman?; font-size-adjust: none; font-stretch: normal?>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">如果您希望每一笔数据列的超级链接都显示相同的固定文字，请将</span><strong>HyperLinkField</strong><span style="font-family: 宋体">数据行的</span><strong>Text</strong><span style="font-family: 宋体">属性设定成所需的文字。图表</span>1<span style="font-family: 宋体">所示者即是一例。</span></div>
<div style="margin: 3pt 0cm 3pt 24pt; text-indent: -24pt"><span style="font-family: 宋体"><img onclick='window.open("http://blog.51cto.com/viewpic.php?refimg=" + this.src)' alt="" src="http://blog.51cto.com/attachment/200712/200712031196689905875.jpg" border="0"></span></div>
<div style="margin: 3pt 0cm 3pt 24pt; text-indent: -24pt"><span style="font-family: 宋体">&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;&nbsp;&nbsp;&nbsp;&nbsp; <strong>图表1</strong></span></div>
<div style="margin: 3pt 0cm 3pt 24pt; text-indent: -24pt"><span style="font-family: 宋体"><span style="font-family: wingdings">q<span Times New Roman?; font-size-adjust: none; font-stretch: normal?>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">如果您希望使用字段的内容作为每一笔数据列之超级链接的文字，请将</span><strong>HyperLinkField</strong><span style="font-family: 宋体">数据行的</span><strong>DataTextField</strong><span style="font-family: 宋体">属性设定成该字段。图表</span>2<span style="font-family: 宋体">所示者即是一例。</span><br />
<br />
<span style="font-family: 宋体">当然，最常与</span><strong>DataTextField</strong><span style="font-family: 宋体">属性搭配使用的不外乎就是</span><strong>DataTextFormatString</strong><span style="font-family: 宋体">属性。我们经常使用</span><strong>DataTextFormatString</strong><span style="font-family: 宋体">属性来格式化取自</span><strong>DataTextField</strong><span style="font-family: 宋体">属性所指定之字段的数据值。图表</span>3<span style="font-family: 宋体">所示者即是一例。</span></span></span></div>
<div style="margin: 3pt 0cm 3pt 24pt; text-indent: -24pt"><span style="font-family: 宋体"><span style="font-family: 宋体"><img onclick='window.open("http://blog.51cto.com/viewpic.php?refimg=" + this.src)' alt="" src="http://blog.51cto.com/attachment/200712/200712031196689950765.jpg" border="0"></span></span></div>
<div style="margin: 3pt 0cm 3pt 24pt; text-indent: -24pt"><span style="font-family: 宋体"><span style="font-family: 宋体">&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>图表2</strong></span></span></div>
<div style="margin: 3pt 0cm 3pt 24pt; text-indent: -24pt"><span style="font-family: 宋体"><span style="font-family: 宋体"><img onclick='window.open("http://blog.51cto.com/viewpic.php?refimg=" + this.src)' alt="" src="http://blog.51cto.com/attachment/200712/200712031196689983046.jpg" border="0"></span></span></div>
<div style="margin: 3pt 0cm 3pt 24pt; text-indent: -24pt"><span style="font-family: 宋体"><span style="font-family: 宋体">&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;&nbsp;&nbsp; <strong>图表3</strong></span></span></div>
<div style="margin: 3pt 0cm 3pt 24pt; text-indent: -24pt"><span style="font-family: 宋体"><span style="font-family: 宋体"><span style="font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;学会如何设定<strong>HyperLinkField</strong><span style="font-family: 宋体">数据行所产生之超级链接的文字之后，接下来就是学习设定超级链接的目标</span>URL<span style="font-family: 宋体">。如果您要让所有的超级链接都连结至相同的</span>URL<span style="font-family: 宋体">，请直接将</span><strong>NavigateUrl</strong><span style="font-family: 宋体">属性设定成所需的</span>URL<span style="font-family: 宋体">。这样的设定虽然最为单纯，但是却也非常不切实际，毕竟就算是连结至相同的网页，也会每一笔数据列连结至相同网页中的不同位置（也就是书签</span> <span style="font-family: 宋体">－</span> BookMark<span style="font-family: 宋体">）。因此，较为实用的应该是</span><strong>DataNavigateUrlFields</strong><span style="font-family: 宋体">属性，原因很简单，它允许您指定某一个字段中的</span>URL<span style="font-family: 宋体">作为连结的目的地（<strong><span style="color: red">请注意此属性的名称是以</span></strong></span><strong><span style="color: red">s</span></strong><strong><span style="color: red; font-family: 宋体">结尾，这是有玄机的，稍后会加以说明</span></strong><span style="font-family: 宋体">）。以图表</span>4<span style="font-family: 宋体">所示者而言，表示以<strong>「网址」</strong>字段中的</span>URL<span style="font-family: 宋体">作为连结的目的地，如此一来，不同的超级链接将会拥有各自的</span>URL<span style="font-family: 宋体">。</span></span></span></span></div>
<div style="margin: 3pt 0cm 3pt 24pt; text-indent: -24pt"><span style="font-family: 宋体"><span style="font-family: 宋体"><span style="font-family: 宋体"><img onclick='window.open("http://blog.51cto.com/viewpic.php?refimg=" + this.src)' alt="" src="http://blog.51cto.com/attachment/200712/200712031196690048468.jpg" border="0"></span></span></span></div>
<div style="margin: 3pt 0cm 3pt 24pt; text-indent: -24pt"><span style="font-family: 宋体"><span style="font-family: 宋体"><span style="font-family: 宋体">&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; <strong>图表4</strong></span></span></span></div>
<span style="font-family: 宋体"><span style="font-family: 宋体"><span style="font-family: 宋体">
<div style="margin: 3pt 0cm"><span style="font-family: 宋体">当然，谈到了</span><strong>DataNavigateUrlFields</strong><span style="font-family: 宋体">属性，绝对不能忘了它的好兄弟</span> <span style="font-family: 宋体">－</span> <strong>DataNavigateUrlFormatString</strong><span style="font-family: 宋体">属性。</span><strong>DataNavigateUrlFormatString</strong><span style="font-family: 宋体">属性最主要的用途是用来格式化超级链接的</span>URL<span style="font-family: 宋体">。举例来说，假设您指派给</span><strong>DataNavigateUrlF