<?xml version="1.0" encoding="UTF-8" ?><?XML-stylesheet type="text/css" href="http://www.goberl.com/Theme/feed.css" ?><rss version="2.0">	<channel>	<title><![CDATA[Goberl]]></title>	<link><![CDATA[http://www.goberl.com/]]></link>	<description><![CDATA[Goberl的博客文章]]></description>	<language>Zh-CN</language>	 <ttl>60</ttl><item>	<title><![CDATA[Oracle EM重建失败]]></title>	<link><![CDATA[http://www.goberl.com/archive/item76.aspx]]></link>	<description><![CDATA[<p>创建时提示：&ldquo;SEVERE: Error creating the repository&rdquo;</p>
<p>Google+测试出的方法，已经试用好几次了。</p>
<p>
<ul>
    <li>
    <ul>
        <li>1.emca -deconfig dbcontrol db -repos drop 先正常删除</li>
        <li>2.删除$ORACLE_HOME/<span style="color: rgb(128, 128, 0); ">主机名_实例名</span>的文件夹</li>
        <li>3.删除$ORACLE_HOME/oc4j/j2ee/OC4J_DBConsole_<span style="color: rgb(128, 128, 0); ">主机名_实例名</span>的文件夹</li>
        <li>4.SQL&gt; drop user sysman cascade;</li>
        <li>&nbsp; SQL&gt; drop role MGMT_USER;</li>
        <li>&nbsp; SQL&gt; drop public synonym MGMT_TARGET_BLACKOUTS;</li>
        <li>&nbsp; SQL&gt; drop public synonym SETEMVIEWUSERCONTEXT;</li>
        <li>&nbsp; SQL&gt; drop user MGMT_VIEW;</li>
        <li>5.emca -deconfig dbcontrol db -repos drop执行了也没啥害处</li>
        <li>6.emca -config dbcontrol db -repos create</li>
    </ul>
    </li>
</ul>
<p>&nbsp; 以上方法在单机、Oracle 10.2.0.4、单实例上测试通过。</p>
<p>&nbsp;</p>
<p>提示：</p>
<p>&nbsp; 重建或删除EM时会导致数据服务器忙，请在空闲时操作。</p>
</p>]]>	</description>	<pubDate>2011-11-25 16:33:11</pubDate>	<category><![CDATA[Oracle]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item76.aspx</guid></item><item>	<title><![CDATA[Enterprise Manager 可访问模式被禁用]]></title>	<link><![CDATA[http://www.goberl.com/archive/item75.aspx]]></link>	<description><![CDATA[<p>&nbsp;突然一早发现Enterprise Manager无法使用了，检查状态，发现服务没有启动，重启服务后，登录网页点击&ldquo;登录&rdquo;依旧不可访问，再检查服务发现服务已经停止&mdash;&mdash;这服务自动停止运行了。Google不到相关内容，待到晚上重新配置EM后发现em服务工作正常，但网页中提示&ldquo;可访问性模式&rdquo;&ldquo;禁用&rdquo;。</p>
<p>&nbsp; Google到的解决办法是修改uix-config.xml中accessibility-mode节点值为accessible。uix-config.xml文件位置官方10.1版本的文档说是$ORACLE_HOME/j2ee/OC4J_EM/applications/em/em/WEB-INF/uix-config.xml，但我在服务器上未找到，查看Oracle Enterprise Manager 10g Database Control Release版本为&nbsp;10.2.0.4.0，最后在$ORACLE_HOME/oc4j/j2ee/applications/em/em/WEB-INF/uix-config.xml中找到，修改值，保存，重启服务，问题解决。</p>
<p>&nbsp;</p>]]>	</description>	<pubDate>2011-11-21 9:40:06</pubDate>	<category><![CDATA[Oracle]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item75.aspx</guid></item><item>	<title><![CDATA[关于更新]]></title>	<link><![CDATA[http://www.goberl.com/archive/item74.aspx]]></link>	<description><![CDATA[<p>自去年年初离开学校开始工作，并在毕业之前&ldquo;敷衍&rdquo;地做了毕业设计，平时实在没有多少空闲时间更新博客了。</p>
<p>在学校时主要用C#做Web开发，偶尔实验WinForm，所使用的数据库也主要在SQL Server、Access、Sqlite这几个。而目前工作使用的却是Delphi+Oracle，刚来的几个月又得熟悉公司业务，直到后来跟进一个系统实施才算真正的开始了Delphi+Oracle之旅，可给我的感觉是被动地浑浑噩噩地学习着、工作着。还是学校的空闲时间多，能够静下心来钻研，工作了难免会顾此失彼。</p>
<p>觉得不幸的是用了Oralce都快8个月了，却感觉自己连门槛都还未入。公司用的Oracle 10g运行于AIX，目前我所做的主要是数据库编程方面，关于服务器维护、数据库管理备份还原都涉入较浅，学习机会是有的，就是没有好好利用。</p>
<p>逛逛CSDN，总是感觉很压抑，大伙开发都用LINQ、Sliverlight了，自己却一个实验体都未产生。</p>]]>	</description>	<pubDate>2011-6-16 23:42:29</pubDate>	<category><![CDATA[咸鱼炒蛋]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item74.aspx</guid></item><item>	<title><![CDATA[挣扎]]></title>	<link><![CDATA[http://www.goberl.com/archive/item73.aspx]]></link>	<description><![CDATA[<p>&nbsp;</p>
<p>努力尝试着做点什么，到如今未有任何结果，继续尝试吧。2011年是个好年头！</p>]]>	</description>	<pubDate>2011-2-20 16:06:07</pubDate>	<category><![CDATA[Dev]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item73.aspx</guid></item><item>	<title><![CDATA[两个正则实例]]></title>	<link><![CDATA[http://www.goberl.com/archive/item72.aspx]]></link>	<description><![CDATA[<p>&nbsp;把一串数字每3位加一个逗号。</p>
<div><pre id='CodecSharp0' class='CodecSharp'><a href='javascript:void(0);' onclick='copyCodeByID(0)'>复制代码</a>

<span class='code-keyword'>string</span> s = <span class='code-str'>&quot;某某的面积是12345678平方米&quot;</span>;

<span class='code-keyword'>string</span> t = Regex.Replace(s, <span class='code-str'>@&quot;(?&lt;=\d)(?=(\d\d\d)+(?!\d))&quot;</span>, <span class='code-str'>&quot;,&quot;</span>);

Console.WriteLine(t); <span class='code-note'>//输出：某某的面积是12,345,678平方米

</span></pre><br />
三行代码实现阿拉伯数字转中文大小写<br />
<pre id='CodecSharp1' class='CodecSharp'><a href='javascript:void(0);' onclick='copyCodeByID(1)'>复制代码</a>

<span class='code-keyword'>using</span> System;

<span class='code-keyword'>using</span> System.Text.RegularExpressions;


<span class='code-keyword'>class</span>Program

{

  <span class='code-note'>//把阿拉伯数字的金额转换为中文大写数字

</span>  <span class='code-keyword'>static</span> <span class='code-keyword'>string</span> ConvertToChinese(<span class='code-keyword'>double</span> x)

  {

    <span class='code-keyword'>string</span> s = x.ToString(<span class='code-str'>&quot;#L#E#D#C#K#E#D#C#J#E#D#C#I#E#D#C#H#E#D#C#G#E#D#C#F#E#D#C#.0B0A&quot;</span>);

    <span class='code-keyword'>string</span> d = Regex.Replace(s, <span class='code-str'>@&quot;((?&lt;=-|^)[^1-9]*)|((?'z'0)[0A-E]*((?=[1-9])|(?'-z'(?=[F-L\.]|$))))|((?'b'[F-L])(?'z'0)[0A-L]*((?=[1-9])|(?'-z'(?=[\.]|$))))&quot;</span>, <span class='code-str'>&quot;${b}${z}&quot;</span>);

    <span class='code-keyword'>return</span> Regex.Replace(d, <span class='code-str'>&quot;.&quot;</span>, <span class='code-keyword'>delegate</span>(Match m) { <span class='code-keyword'>return</span> <span class='code-str'>&quot;负元空零壹贰叁肆伍陆柒捌玖空空空空空空空分角拾佰仟萬億兆京垓秭穰&quot;</span>[m.Value[0] - '-'].ToString(); });

  }


  <span class='code-keyword'>static</span> <span class='code-keyword'>void</span> Main()

  {

    Random r = <span class='code-keyword'>new</span> Random();

    <span class='code-keyword'>for</span> (int i = 0; i &lt; 10; i++)

    {

      <span class='code-keyword'>double</span> x = r.Next() / 100.0;

      Console.WriteLine(<span class='code-str'>&quot;{0,14:N2}: {1}&quot;</span>, x, ConvertToChinese(x));

    }

  }

}

/* 可能的输出：

  5,607,400.68: 伍佰陆拾萬柒仟肆佰元陆角捌分

  2,017,723.33: 贰佰零壹萬柒仟柒佰贰拾叁元叁角叁分

    751,181.17: 柒拾伍萬壹仟壹佰捌拾壹元壹角柒分

  7,849,851.53: 柒佰捌拾肆萬玖仟捌佰伍拾壹元伍角叁分

  2,629,143.90: 贰佰陆拾贰萬玖仟壹佰肆拾叁元玖角

 13,461,629.68: 壹仟叁佰肆拾陆萬壹仟陆佰贰拾玖元陆角捌分

  4,594,391.16: 肆佰伍拾玖萬肆仟叁佰玖拾壹元壹角陆分

 13,046,560.60: 壹仟叁佰零肆萬陆仟伍佰陆拾元陆角

 13,041,371.21: 壹仟叁佰零肆萬壹仟叁佰柒拾壹元贰角壹分

 20,639,609.44: 贰仟零陆拾叁萬玖仟陆佰零玖元肆角肆分

*/

</pre><br />
<br />
来源:http://topic.csdn.net/u/20101126/14/636C5E88-2297-4CE6-BF40-E6427C2799A4.html</div>]]>	</description>	<pubDate>2010-12-3 8:53:21</pubDate>	<category><![CDATA[Dev]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item72.aspx</guid></item><item>	<title><![CDATA[非规范化HTML文档带来的Bug]]></title>	<link><![CDATA[http://www.goberl.com/archive/item71.aspx]]></link>	<description><![CDATA[<p>&nbsp;&nbsp;&nbsp;一页面显示数条记录，为了让每条记录都具有编辑、删除功能，于是乎在每个tr之外均添加一form，在td之内添加一submit，可发现在onsubmit中获取form内的任何表单均提示不存在。辗转测试，丢弃table，tr，td后数据才获取正常。为了方便格式控制，又不想多写js，只好为每条记录生成一table。</p>
<div>&nbsp;&nbsp;非规范html带来的高隐藏性Bug，谨记。</div>
<div>&nbsp;</div>]]>	</description>	<pubDate>2010-11-30 14:37:58</pubDate>	<category><![CDATA[Bug回收站]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item71.aspx</guid></item><item>	<title><![CDATA[Visual Studio2010目标框架没有2.0和3.0]]></title>	<link><![CDATA[http://www.goberl.com/archive/item70.aspx]]></link>	<description><![CDATA[<div><strong><span style="font-size: larger; ">现象</span></strong></div>
<div>&nbsp;&nbsp;右击项目，选择&ldquo;属性&rdquo;，进入&ldquo;应用程序&rdquo;，&ldquo;目标框架&rdquo;中只有.NET Framework 4和.NET Framework 4 Client Profile，没有.NET Framework 2.0、3.0和3.5。</div>
<div>&nbsp;&nbsp;打开项目时或提示：<br />
<span style="color: rgb(128, 128, 0); ">C#项目&ldquo;*&rdquo;针对是&ldquo;NETFramework，Vesion=v2.0&rdquo;，此计算机上没有安装它</span>&hellip;&hellip;</div>
<div><img width="500" height="299" alt="" src="/fckeditor/FCKPro/upLoadFiles/image/vs2010-1.jpg" /></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><strong><span style="font-size: larger; ">解决办法</span></strong></div>
<ol>
    <li>&nbsp;&nbsp;判断系统是否安装了.NET Framework 3.5 SP1，其在控制面板中的名称为Microsoft .NET Framework 3.5 SP1，若控制面板中不存在，则需要安装此组件；</li>
    <li>&nbsp;&nbsp;若是安装了，则可能是由于其安装的组件有问题，可用工具（http://blogs.msdn.com/b/astebner/archive/2008/10/13/8999004.aspx）校验.NET Framework&nbsp;或者重新安装；</li>
    <li>&nbsp;&nbsp;若是未安装，建议下载.NET Framework 3.5 SP1完整版并安装http://download.microsoft.com/download/2/0/e/20e90413-712f-438c-988e-fdaa79a8ac3d/dotnetfx35.exe；</li>
</ol>
<div>&nbsp;</div>]]>	</description>	<pubDate>2010-11-9 17:33:13</pubDate>	<category><![CDATA[Dev]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item70.aspx</guid></item><item>	<title><![CDATA[Oracle“load data”导入CSV数据注意事项]]></title>	<link><![CDATA[http://www.goberl.com/archive/item69.aspx]]></link>	<description><![CDATA[<ol>
    <li>注意CSV中的&ldquo;数字型数据&rdquo;变成科学计数数据<br />
    &nbsp; 例如：XLS中的&ldquo;1542264451451545-E10&rdquo;保存为csv后，再用Excel打开，&ldquo;1542264451451545-E10&rdquo;可能会&ldquo;变质&rdquo;<br />
    &nbsp; 所以：最好不要随便打开已保存的CSV文档，若必要要打开，可用记事本等非格式软件打开；</li>
    <li>在保存到CSV之前，请替换掉特殊字符.<br />
    &nbsp;特殊字符包括：半角单引号、半角双引号、分隔符（默认是半角逗号）。替换的时候可以用全角替换他们，若业务需要导入数据库后再替换回来；</li>
    <li>若原始XLS中的数据存在空格，请用记事本打开保存的CSV文件，把里面的半角双引号替换为特殊字符， 例如&ldquo;)(^_^)(&rdquo;,在导入数据库后再把特殊字符替换为空；</li>
    <li>导入的数据库表的列varchar2(长度)的长度必须大于等于各个数据的长度（当然，汉字占2个位）；</li>
    <li>导入的CSV中，部分行的部分列为空值时，请在&ldquo;fields terminated by ','&rdquo;之后加入&ldquo;trailing&nbsp;&nbsp; nullcols&rdquo;</li>
</ol>
<p>&nbsp;</p>
<p>上述中的2、3、4、5处理不当都会导致导入的CSV数据只能是部分，但不会出现任何错误提示。以上基于Oracle 9I数据库整理！</p>]]>	</description>	<pubDate>2010-8-20 19:13:57</pubDate>	<category><![CDATA[Dev]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item69.aspx</guid></item><item>	<title><![CDATA[杂记]]></title>	<link><![CDATA[http://www.goberl.com/archive/item68.aspx]]></link>	<description><![CDATA[<p><span style="font-size: larger;"><strong>1.随机查询链接</strong></span><br />
SELECT TOP 10 * FROM categories<br />
ORDER BY NEWID()<br />
<br />
<strong><span style="font-size: larger;">2..提高性能</span></strong><br />
&nbsp;&nbsp;&nbsp; 对建立了索引的列最好设置默认值，以去除is (not) null查询<br />
&nbsp;&nbsp;&nbsp; 少用Join、SQL连接字符串的查询<br />
&nbsp;&nbsp;&nbsp; 使用Like时，通配符不要放在句首<br />
&nbsp;&nbsp;&nbsp; 用&lt;、&gt;代替not<br />
&nbsp;&nbsp;&nbsp; 用EXITS代替IN<br />
&nbsp;&nbsp;&nbsp; 用&gt;=代替&gt;,&gt;2 TO &gt;=3<br />
&nbsp;&nbsp;&nbsp; OUTER JOIN 与 INNER JOIN 的处理方式是不同的：对于 INNER JOIN 表，优化器会尝试重新排列联接顺序，而对于 OUTER JOIN 表则不会。外部表（LEFT OUTER JOIN 中的左表和 RIGHT OUTER JOIN 中的右表）将首先访问，然后才会访问内部表。这一固定的联接顺序可能会导致执行计划不能达到最优（创建索引后，inner join更具有优势）。<br />
&nbsp;&nbsp;&nbsp; <strong>使用非规范化数据库 </strong><br />
规范化的数据库可防止数据存在功能相关性，以便轻松、高效地更新数据库。但是，查询数据库时可能需要联接许多表来组合信息。随着联接表数目的增多，查询运行时间会大大增加。因此，规范化的数据库并不一定是最佳的选择。如果数据库适当程度地不合规范，则可以减少必须联接在一起的表的数目，而不会使更新过程过于复杂。这通常是一个很好的折衷办法。<br />
&nbsp;&nbsp;&nbsp;<strong>&nbsp; 注意</strong>&nbsp; <br />
通常，如果有相当多的查询需要联接五个或六个以上的表，则应考虑使用非规范化数据库。 （http://msdn.microsoft.com/zh-cn/library/ms172432(SQL.90).aspx）<br />
&nbsp;&nbsp;&nbsp; 与固定长度列相比，可变长度列的缺点是一些操作的效率不高。例如，如果可变长度列开始时很小，而某 UPDATE 子句使其显著增大，则可能就要重新定位记录。此外，频繁的更新会导致数据页随着时间推移变得比较零碎。因此，在数据长度变化不大并且需要频繁进行更新时，建议使用固定长度列。<br />
&nbsp;&nbsp;&nbsp; 创建长度较小的行 <br />
&nbsp;&nbsp;&nbsp; 使用长度较小的键 <br />
&nbsp;&nbsp;&nbsp; 全文搜索性能（http://msdn.microsoft.com/zh-cn/library/ms142560(SQL.90).aspx）<br />
<br />
<span style="font-size: larger;"><strong>3.SQL区分大小写</strong></span><br />
区分大小写:select * from table where col='semye' collate Chinese_PRC_CS_AI<br />
不区分大小写:select * from table where col='semye' collate Chinese_PRC_CI_AI<br />
<br />
<br />
&nbsp;</p>]]>	</description>	<pubDate>2010-4-30 22:18:22</pubDate>	<category><![CDATA[Dev]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item68.aspx</guid></item><item>	<title><![CDATA[凤凰肉其实是山鸡肉]]></title>	<link><![CDATA[http://www.goberl.com/archive/item67.aspx]]></link>	<description><![CDATA[<p>有个很有趣的现象。比如买MP3，市场上几十上百（低于500）的Mp3比比皆是，可人们花了那个钱买了还是觉得赶不上上千元的iPod MP3&mdash;&mdash;真实奇迹啊，一个公司让成本只有数百RMB的产品卖你2000RMB，你还觉得自己那个酷、那个神气、那个得意，从来不认为自己是冤大头，难道不奇迹么？当然如果把iPod的核心技术算上，你会觉得不只那个价，可其成本又会比其他的Mp3贵得了多少呢？如果你认为独一无二是无价的，那我也没话说了。<br />
&nbsp; 又或者买一双Nike鞋吧，一听Nike，哇，挺牛的国际知名品牌，说不定你买的鞋子就在中国或者越南生产的。生产后送到美国打上标签，再运回中国销售，过了两次洋，这&ldquo;山鸡就变凤凰&rdquo;了。其实你吃的凤凰肉还是自己林子里长的山鸡。<br />
&nbsp; 又或者诺基亚、摩托罗拉手机吧，在未上壳之前，说不定就来自同一家生产厂家，可能其手机设计都来自同一家公司。不要以为诺基亚就比摩托罗拉强，他们或许在同一个厂家生产，甚至使用相同原材料。<br />
&nbsp; 为什么会发生这些奇怪的现在，人们宁愿花更多的Moeny去购买相同质量和性能的产品，仅仅因为他们是品牌或者服务（又有多少人真正享用了这些服务）。人们在购买这些品牌商品的时候除了商品的产品价值外，更获得了品牌价值，为了心理满足，必须为之付出代价的。<br />
&nbsp; 我不得不说，中国，真的缺少自己的品牌。生产环节的盈利是产品链中盈利最小的。可能这是中国当前国情决定的，但还是希望中国能多出几个具有国际竞争力的公司&mdash;&mdash;强调一下，当然不是中国移动、中国石油那种。</p>]]>	</description>	<pubDate>2009-12-29 11:59:17</pubDate>	<category><![CDATA[咸鱼炒蛋]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item67.aspx</guid></item><item>	<title><![CDATA[搜狗浏览器来了]]></title>	<link><![CDATA[http://www.goberl.com/archive/item66.aspx]]></link>	<description><![CDATA[<p>今晚搜狗输入法弹窗，我不小心点了&ldquo;确定&rdquo;安装了搜狗浏览器，在安装过程中我想点取消都没法点。好像那个弹窗也只有在右上角有常规的关闭按钮，中间只有&ldquo;确定&rdquo;。</p>
<p><br />
进来看界面还算不错，那个独立页面防假死、防无响应也很创新，用了一会，明显感觉比IE6快（当前使用的PC是IE6）所以跑到贴吧看看大伙的体验，看要不要卸载它。不过呢，发现贴吧貌似有很多枪手。还有搜狗浏览器官网说永久免费，其前提应该是IE已经付费了吧（IE的Money应该包含在Windows中吧，当然很多人包括我都是用的D版，对它免费不免费没什么概念）</p>
<p><br />
我开了搜狗浏览器20分钟左右，9个标签，一看任务管理器。发现这家伙吃了我65.46+54.57+10.20+13.85=163.88MB内存。其内存名称和所用内容如下：<br />
<span style="color: #808000">setask.exe,65.46MB<br />
setask.exe,54.57MB<br />
setask.exe,10.20MB<br />
SogouExplorer.exe,13.85MB<br />
65.46+54.57+10.20+13.85=163.88MB</span></p>
<p><br />
搜狗推出浏览器是说快（血本提供代理的原因？）、标签页独立稳定，360浏览器除了说快，更注重安全。看来他们都分了一杯属于自己的羹。&nbsp;</p>
<p>Chrome浏览器我也用了一段时间，感觉好多网页打开速度特慢（虽然Chrome运行JavaScript的速度很快），还有好多网页显示不正常（这个主要是由于chrome太标准化了，而网页制作者大多只编写适合IE的）</p>
<p><br />
我平时都用Firefox，在它之前用遨游，有一段时间不知道是由于电脑出故障还是咋的，遨游一而再再而三崩溃（包括系统重装、浏览器换版本），所以不得不另觅一款浏览器。当时准备在IE7和Firefox上做选择。我就用手动方式测试：<br />
不断地新建标签页，然后输入相同网址，直到浏览器崩溃或者反应超慢的时候为止，以最大标签数为衡量标准。当然创建标签的速度是能多快就多快。<br />
结果发现：<br />
IE7通常在10到20个的时候，就直接崩溃（不是无响应），而Firefox直到40个左右的时候才反应超慢或则偶尔崩溃，由此我对所有基于IE内核的浏览器都排斥了，那些采用了IE内核的浏览器再吹捧安全、稳定、快速都有其局限性；这也是为什么Chorme给我的印象虽然不好，但我相信它的发展空间。人家现在完全可以做更多贴近于用户的功能，而他们更关心的是内核，一个浏览器的内核在一定程度上决定着它未来的命运，这正是Google着眼于未来的网络操作系统的卓越眼光。</p>
<p><br />
当我写这篇文章写到一半的时候（为了查看开了几个标签页），不小心把正在打字的标签页关闭了，习惯性（Firefox）地右击鼠标发现没有&ldquo;恢复关闭的标签页&rdquo;，觉得这一点还真的只有Firefox才有，我喜欢。</p>
<p><br />
其实我喜欢Forefox的原因主要是由于其稳定性和扩展性，当然安全性不用说了吧，并且是开源、免费、跨平台的。比如上网上银行、支付宝什么的，需要使用IE才能正常访问，仅仅需要安装一个IE Tab，当访问这些&ldquo;特殊&rdquo;网站的时候，会自动切换到IE内核浏览模式；需要什么网络书签、导航什么的直接下载一个扩展就是了。近来我还发现了Fifefox的一个奇特之处&mdash;&mdash;当点击网络上的Email链接的时候，Firefox直接询问我是否选择Gmail、Yahoo，还是系统默认的邮件发送软件，而选择前两者似乎都直接打开相应的Email页面，如果账号已经登录，直接填写标题和内容，点击发送就是了，还真不错啊。&nbsp;</p>]]>	</description>	<pubDate>2009-12-15 21:50:32</pubDate>	<category><![CDATA[咸鱼炒蛋]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item66.aspx</guid></item><item>	<title><![CDATA[Information About Lucene]]></title>	<link><![CDATA[http://www.goberl.com/archive/item65.aspx]]></link>	<description><![CDATA[<p><strong>Lucene简介</strong><br />
<span style="color: rgb(128, 128, 0);">http://www.chedong.com/tech/lucene.html</span></p>
<p><strong>Luncene初见索引、检索</strong><br />
<span style="color: rgb(128, 128, 0);">http://topic.csdn.net/u/20080408/17/a9095641-b014-4223-9b68-6c694fd242f5.html</span></p>
<p>&nbsp;</p>
<p><strong>Luncene源码下载</strong><br />
<span style="color: rgb(128, 128, 0);">http://apache.freelamp.com/lucene/java/lucene-3.0.0-src.zip</span></p>
<p>&nbsp;</p>
<p><strong>Luncene jar下载</strong><br />
<span style="color: rgb(128, 128, 0);">http://apache.freelamp.com/lucene/java/lucene-3.0.0.zip</span></p>
<p>&nbsp;</p>
<p><strong>Lucene API</strong><br />
<span style="color: rgb(128, 128, 0);">http://lucene.apache.org/</span></p>
<p>&nbsp;</p>
<p><strong>Luncene Demo解说</strong><br />
<span style="color: rgb(128, 128, 0);">http://lucene.apache.org/java/3_0_0/demo</span></p>
<p>&nbsp;</p>
<p><strong>解决Luncene Demo中文无法索引</strong><br />
<span style="color: rgb(128, 128, 0);">http://blog.eood.cn/archives/247/</span></p>
<p>&nbsp;</p>
<p><strong>Luncene FQ</strong><br />
<span style="color: rgb(128, 128, 0);">http://wiki.apache.org/lucene-java/LuceneFAQ</span></p>
<p>&nbsp;</p>
<p><strong>Luncene索引HTML</strong><br />
<span style="color: rgb(128, 128, 0);">http://wiki.apache.org/lucene-java/LuceneFAQ#How_can_I_index_HTML_documents.3F</span></p>
<p><strong>Luncene索引OpenDocument (aka OpenOffice.org), RTF, Microsoft Word, Excel, PowerPoint,Visio, etc</strong><br />
<span style="color: rgb(128, 128, 0);">http://wiki.apache.org/lucene-java/LuceneFAQ#How_can_I_index_file_formats_like_OpenDocument_.28aka_<br />
OpenOffice.org.29.2C_RTF.2C_Microsoft_Word.2C_Excel.2C_PowerPoint.2C_Visio.2C_etc.3F</span></p>
<p>&nbsp;</p>
<p><strong>Luncene索引PDF</strong><br />
<span style="color: rgb(128, 128, 0);">http://wiki.apache.org/lucene-java/LuceneFAQ#How_can_I_index_PDF_documents.3F</span></p>
<p><strong>Luncene索引中文、日文、韩文</strong><br />
<span style="color: rgb(128, 128, 0);">http://wiki.apache.org/lucene-java/LuceneFAQ#Can_I_use_Lucene_to_index_text_in_Chinese.2C_<br />
Japanese.2C_Korean.2C_and_other_multi-byte_character_sets.3F</span></p>
<p>&nbsp;</p>
<p><strong>编码介绍</strong><br />
<span style="color: rgb(128, 128, 0);">http://hi.baidu.com/baseetoo/blog/item/951b612a05ffd3f0e7cd406c.html</span></p>
<p>&nbsp;</p>
<p><strong>UFT8转换到GB2312</strong><br />
<span style="color: rgb(128, 128, 0);">http://www.cnblogs.com/comsteed/articles/1126023.html</span></p>
<p>&nbsp;</p>
<p><strong>GB2312转换到UFT8</strong><br />
<span style="color: rgb(128, 128, 0);">http://topic.csdn.net/t/20051026/10/4350730.html</span></p>
<p>&nbsp;</p>
<p><strong>获取文档编码</strong><br />
<span style="color: rgb(128, 128, 0);">http://hi.baidu.com/i7521/blog/item/50d51d55166ecbcdb645ae01.html<br />
http://dev.csdn.net/Develop/article/10/10961.shtm<br />
http://dev.csdn.net/Develop/article/10/10962.shtm</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>]]>	</description>	<pubDate>2009-12-12 18:20:39</pubDate>	<category><![CDATA[互联网]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item65.aspx</guid></item><item>	<title><![CDATA[关于Linux的一点想法]]></title>	<link><![CDATA[http://www.goberl.com/archive/item64.aspx]]></link>	<description><![CDATA[<p>以前玩了一段时间Linxu，不但在Vmware中玩了，还把自己系统给装上了XP/Linux的双系统，可最终都因无法解决Linux的问题、应用软件 的不支持的，把Linux给卸载了，一切想学习Linux操作系统的计划都破产在那个陌生的Red Hat上，记得好像当时输入法坏了，不能输入汉字，搞了很久都没OK。</p>
<p>最近又想要学Linux，主要是因为学习Java的缘故，大家都知道Java最大的优点就在于其超强的迁移能力，无论是Windows还是Unix还是 Mac，只要装上Java虚拟机，那个Java程序是畅快的跑。而目前大型的服务器采用的系统都是Linux、Unix，很少网络巨人使用微软操作系统做服务器 （微软除外）。我是想既然学Java，那就把那个Java的极致表现出来，写Linux上的Java，可能会奇怪，在Widnows上写好了放在 Linux上跑就是了，可调试咋办呢？没人教我如何配置一台Linux电脑来跑JSP、PHP，虽然网上有那么多的教材，可都是那种一蹴而就的，可能当时 配置好了，可出问题了又不能解决。所以啊，我想好好的学Linux，学会使用它配置服务器环境，学会管理Linux服务器。</p>
<p>为了装双系统、也为了备份好我电脑里面的一些重要软件和资料，我前天&ldquo;冲动&rdquo;地买了个移动硬盘，等备份好数据后，再来从硬盘安装双系统吧。</p>
<p>说道Linxu，又不得不说Oracle，今天面试的时候，面试官问我对它了解多少，我就说仅仅是曾经好奇拿来测试了下，可能他仍然不明白我具体了解什 么，就问我&ldquo;Oracle有什么特点&rdquo;。我一想，有啥特点呢？就随便说了&ldquo;处理能力比MS SQL强、能够在多种OS上运行&rdquo;，也不知道咋的了。我以前电脑确实是装了Oracle，因电脑配置太低，装上后卡得要命，没两天我就把它给卸载了。我也 不知道Oracle有啥特点，只知道中石油、中石化这些大公司爱用&mdash;&mdash;他们的数据量太大了。而银行呢都不用Oracle，用DB2去了&mdash;&mdash;银行有钱啊。</p>]]>	</description>	<pubDate>2009-11-6 21:33:35</pubDate>	<category><![CDATA[Google微软]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item64.aspx</guid></item><item>	<title><![CDATA[Word转换到PDF、SWF]]></title>	<link><![CDATA[http://www.goberl.com/archive/item63.aspx]]></link>	<description><![CDATA[<p>最近在填写简历的过程中使用了pdf格式的文档，<wbr></wbr>偶然发现一个把<strong>Word转换为pdf或wsf格式</strong>的转换器&mdash;&mdash;<a href="http://www.adobe.com/products/flashpaper/" target="_blank">FlashPaper2</a>，<wbr></wbr>确实不错。</p>
<p>如果在Word中设置好格式，直接另存为网页文件，<wbr></wbr>会 失去本来的格式，原来不错的外观可能会&ldquo;支离破碎&rdquo;。而另存为swf格式，即使word里面插入了图片，也仍可保留格式、外观，还可以防止Copy，并且 可以在没有装Office的电脑上查看该文档，即使下载到桌面上仍然可以用浏览器、暴风影音等查看，这对于那些只希望别人查看,不希望被复制、被搜索引擎索引的文档实在是一件好事。</p>
<p>pdf这种文档对于我来说有点像Linux给我的印象，都说他好，可使用它的人却远没有使用Word的人多（国内至少如此，可能都是用的盗版Office 或者wps），一般用得较多的地方是论文库中的文档，通常在图书馆论文库搜索的文章都提供pdf格式下载，使用pdf是免费的，不用给人缴纳Moeny。</p>
<p><a href="http://www.adobe.com/products/flashpaper/" target="_blank">FlashPaper2</a>有30天的试用期，不过网上到处是注册码。在中国就是这样，盗版、山寨横行，都在用微软的系统，可没见几个正版的&mdash;&mdash;也可能是学校和个人电脑这种现象才普遍。微软不打击教育方面的盗版，让这些学生们在学校用Windows就用上瘾，走上社会搞商业了，再来&ldquo;勒索&rdquo;。像操作系统这种需要消耗大量时间和精力才能搞懂的东 西一旦用习惯了，是很难让消费者再去习惯另一种系统。</p>]]>	</description>	<pubDate>2009-11-6 21:04:34</pubDate>	<category><![CDATA[互联网]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item63.aspx</guid></item><item>	<title><![CDATA[改版后的Bug]]></title>	<link><![CDATA[http://www.goberl.com/archive/item62.aspx]]></link>	<description><![CDATA[<p>前几天就发现阅读次数总是显示1，以为问题出在JS上，昨晚检查项目文件终于发现在更新到数据库的时候没有累加，而是直接赋值1，这种逻辑性错误实在难找。在睡觉前更新了dll，现在应该能够正常工作了。</p>
<p>昨天学校双选了&mdash;&mdash;没戏。专业签了10多个销售的；一个软件开发的，在新疆太远了，没努力争取。现在觉得自己学的东西没一点优势，自己会的，别人也会。瞄上个不错的岗位，对他有兴趣，可要求又达不到&hellip;&hellip;</p>
<p>革命尚未成功，同志仍需努力！</p>
<p>&nbsp;</p>]]>	</description>	<pubDate>2009-11-3 9:09:22</pubDate>	<category><![CDATA[Dev]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item62.aspx</guid></item><item>	<title><![CDATA[Blog程序改版]]></title>	<link><![CDATA[http://www.goberl.com/archive/item61.aspx]]></link>	<description><![CDATA[<p>上周三到周末把博客改版了，但只修改了后台程序，页面皮肤没有修改。</p>
<ol>
    <li>采用了三层架构；</li>
    <li>增加了页面的关键词描述；</li>
    <li>部分地方使用多线程；</li>
    <li>丢弃以前的web服务，采用jQuery调用Ashx实现ajax；</li>
    <li>验证码字符增加随机旋转；</li>
    <li>优化了评论、友情链接管理模块；</li>
    <li>修复C#高亮代码模块的Bug；</li>
    <li>修改RSS仅显示最近发表的12篇新闻；</li>
    <li>tag排序的文章页添加分页功能；</li>
    <li>全局排序分页、分类排序分页、tag排序分页每页显示文章数和右侧菜单中各个模块调用数均采用了统一配置文件；</li>
    <li>可手动设置分类列表的排序情况。</li>
    <li>优化了分页查询语句</li>
</ol>
<p>这次改版最满意的是使用了三层架构，使用它非常有利于以后的升级。这几天在观察运行情况<img alt="" src="/fckeditor/editor/images/smiley/myface/img69.gif" /></p>]]>	</description>	<pubDate>2009-10-27 13:49:08</pubDate>	<category><![CDATA[Dev]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item61.aspx</guid></item><item>	<title><![CDATA[利用缓存过期在ASP.NET中实现定时器]]></title>	<link><![CDATA[http://www.goberl.com/archive/item60.aspx]]></link>	<description><![CDATA[<p>在B/S结构中要实现定时器（或者说是一个事务）实在不是一件好办的事。可当你在网上搜索&ldquo;<strong>ASP.NET定时器</strong>&rdquo;的时候，你会发现搜索结果是如此的多，可这大多数结果中的代码健壮性都是那样的脆弱&mdash;&mdash;没有考虑诸如IIS进程的<strong>自然消亡</strong>、<strong>IIS进程的故障崩溃</strong>、<strong>重启服务器</strong>等等因素。这些不可捕捉的错误会让你的定时器失去定时的功能。可能会有人问，为什么要用Web程序做计时器呢？自己添加一个Windows服务或者在数据库中添加一个作业不就解决了么？可事实上，又有多少人对自己购买的虚拟主机具有如此权限呢？如果你用的是自己的服务器或者更高权限的服务器，那此文对你的确是多余了。</p>
<p>我曾经为ASP.NET中的<span style="color: rgb(128, 128, 0);">Application_End</span>感到窃喜，以为有了它，以上提及的自然消亡、故障崩溃都可迎刃而解了，可经过自己的实践发现那个<span style="color: rgb(128, 128, 0);">Application_End</span>真的是很无助&mdash;&mdash;你在该代码段真的是nothing to do。国内搜索到的所谓ASP.NET定时器几乎都是采用<span style="color: rgb(128, 128, 0);">System.Thread</span>进程监控实现的，要让Thread在IIS进程中保持长期(比如1年365天时时刻刻)的稳定性实在是不敢打包票。</p>
<p>最后我在CodeProject上找到一篇文章<span style="text-decoration: underline;">《</span><a target="_blank" href="http://www.codeproject.com/KB/aspnet/ASPNETService.aspx">Simulate a Windows Service using ASP.NET to run scheduled jobs</a>》（在ASP.NET中模拟Widnows服务执行计划任务）。在这篇文章中，他利用<strong>缓存的过期</strong>来实现定时器功能。在ASP.NET中，当你添加缓存的时候，会有一个<strong>缓存回调函数</strong>让你同时加入，表示当缓存过期被系统清除的时候，你可以在这个回调函数中做一些事情。缓存回调函数正是实现ASP.NET定时器的重要基石。假设我们在00:00:00时刻加入一个缓存对象，缓存的过期时间我们设置为00:02:00，当到达00:02:00或者更提前的时候，缓存将被系统回收，当系统通知缓存被回收的时候我们再次添加一个缓存，如此循环往复（<strong>缓存被添加-&gt;过期-&gt;再次添加-&gt;过期&hellip;&hellip;</strong>）从而模拟出了钟表秒针。当每一次缓存过期的时候我们都检查是否有需要执行的事务，有则执行，然后再次添加一个缓存，从而模拟出了定时器。</p>
<p>但是要想添加缓存，必须有用户请求Web服务器才能使用<span style="color: rgb(128, 128, 0);">Cache</span>。所以，在缓存过期的时候，除了检查是否有事务需要执行外，还要用<span style="color: rgb(128, 128, 0);">WebClient</span>（或者其他方法）请求我们的Web页面，在页面被请求的时候添加缓存。</p>
<p>上面的思路已经基本模拟出了定时器的功能，但对于服务器重启、IIS故障仍然没有解决。《Simulate a Windows Service using ASP.NET to run scheduled jobs》中提到，可以把Google Robots抓取你网页的频率设置大一点，当出现上述情况时，以尽快的速度产生Web请求。只要有人（或者机器人）在访问你的Web程序，缓存定时器（我们把它称为&ldquo;<strong>缓存时钟</strong>&rdquo;吧）就可以正常工作，而他的工作是由系统自行维护的，而不是Thread进程维护，所以稳定性会有很大的提高。<u>经过我的实践，只要服务器没有重启、IIS进程没有崩溃，上述中采用<em>在缓冲过期时请求Web页面</em>（WebClient）的行为是不会让IIS进程自然消亡的（缓存过期时间长短、服务器配置也会影响）。（下划线文字的描述与事实不符，观测的结果可能受到网络蜘蛛的影响）</u>具体如何实现，请看下文。</p>
<p>&nbsp;</p>
<pre class="CodecSharp" id="CodecSharp0"><a onclick='copyCodeByID(0)' href="javascript:void(0);">复制代码</a>

<span class="code-keyword">using</span> System;
<span class="code-keyword">using</span> System.Data;
<span class="code-keyword">using</span> System.Net;
<span class="code-keyword">using</span> System.Configuration;
<span class="code-keyword">using</span> System.Web;
<span class="code-keyword">using</span> System.Text;
<span class="code-keyword">using</span> System.Web.Caching;
<span class="code-keyword">using</span> System.Web.Security;
<span class="code-keyword">using</span> System.Web.UI;
<span class="code-keyword">using</span> System.Web.UI.WebControls;
<span class="code-keyword">using</span> System.Web.UI.WebControls.WebParts;
<span class="code-keyword">using</span> System.Web.UI.HtmlControls;

<span class="code-keyword">public</span> <span class="code-keyword">class</span>CacheTimer

{

    <span class="code-keyword">const</span> <span class="code-keyword">string</span> logPath = <span class="code-str">@&quot;d:\cacheLogs\cacheLog.txt&quot;</span>;
    <span class="code-keyword">const</span> <span class="code-keyword">string</span> cacheKeyName = <span class="code-str">&quot;myCacheTimer&quot;</span>;<span class="code-note">//缓存的名字<br /><br /><br /></span>    <span class="code-keyword">const</span> <span class="code-keyword">string</span> rawUrl = <span class="code-str">&quot;http://localhost/CacheTimer/CacheTimmer.aspx&quot;</span>;<span class="code-note">//缓存过期时请求的页面地址<br /><br /></span>    <span class="code-keyword">public</span> <span class="code-keyword">void</span> RegistCacheTimmer()

    {

        <span class="code-keyword">if</span> (HttpContext.Current.Cache[cacheKeyName] != <span class="code-keyword">null</span>) <span class="code-keyword">return</span>;
        <span class="code-keyword">try</span>
        {

            HttpContext.Current.Cache.Add(cacheKeyName, '1', <span class="code-keyword">null</span>,
                DateTime.Now.AddSeconds(12), Cache.NoSlidingExpiration,
                CacheItemPriority.High,
                <span class="code-keyword">new</span> CacheItemRemovedCallback(CacheItemOnRemoved));
            WriteCacheLog(<span class="code-str">&quot;缓存时钟注册成功&quot;</span>);   
        }
        <span class="code-keyword">catch</span> (Exception e)
        {
            WriteCacheLog(<span class="code-str">&quot;缓存时钟注册失败:&quot;</span> + e.Message);
        }
    }
    <span class="code-keyword">protected</span> <span class="code-keyword">void</span> CacheItemOnRemoved(<span class="code-keyword">string</span> key, <span class="code-keyword">object</span> <span class="code-keyword">value</span>, CacheItemRemovedReason reason)
    {  
        <span class="code-keyword">if</span> (key == cacheKeyName)
        {   
            ExeJob();    
            RequestWebPage();         
        }
    }

    <span class="code-keyword">protected</span> <span class="code-keyword">void</span> ExeJob()
    {

        WriteCacheLog(<span class="code-str">&quot;被执行了&quot;</span>);   
        <span class="code-note">//如果日期的天数能被7整除、下午13点到13点15分的时候，则执行<br /><br /><br /></span>        <span class="code-keyword">if</span> (DateTime.Now.Day % 7 == 0 &amp;&amp; DateTime.Now.Hour == 13 &amp;&amp; DateTime.Now.Minute &lt;= 15)

        {
            <span class="code-note">//执行数据操作或者其他任务<br /><br /></span>        }
    }
    <span class="code-keyword">protected</span>  <span class="code-keyword">void</span> RequestWebPage()
    {
        WebClient wc = <span class="code-keyword">new</span> WebClient();
        wc.DownloadData(rawUrl);
    }

    <span class="code-keyword">public</span> <span class="code-keyword">static</span> <span class="code-keyword">void</span> WriteCacheLog(<span class="code-keyword">string</span> logInfor)
    {
        <span class="code-keyword">try</span>
        {
            System.IO.StreamWriter sw = <span class="code-keyword">new</span> System.IO.StreamWriter(logPath, <span class="code-keyword">true</span>, Encoding.GetEncoding(<span class="code-str">&quot;GB2312&quot;</span>));
            sw.WriteLine(DateTime.Now.ToString() + <span class="code-str">&quot;   &quot;</span> + logInfor);
            sw.Close();
            sw.Dispose();
        }
        <span class="code-keyword">catch</span>
        {

           <span class="code-note">//调试的时候注意是否对该文件有写权限<br /><br /></span>        }
    }
} 

</pre>
<p>&nbsp;</p>
<ol>
    <li>添加缓存:<span style="color: rgb(128, 128, 0);">RegistCacheTimmer</span></li>
    <li>请求页面:<span style="color: rgb(128, 128, 0);">RequestWebPage</span></li>
    <li>执行任务:<span style="color: rgb(128, 128, 0);">ExeJob</span></li>
    <li>缓存过期时候执行请求页、执行任务:<span style="color: rgb(128, 128, 0);">CacheItemOnRemoved</span></li>
    <li>写日志的方法:<span style="color: rgb(128, 128, 0);">WriteCacheLog</span></li>
</ol>
<p>然后在Global.asax文件中添加下列代码段：</p>
<p>&nbsp;</p>
<pre class="CodecSharp" id="CodecSharp1"><a onclick='copyCodeByID(1)' href="javascript:void(0);">复制代码</a>
   <span class="code-keyword">void</span> Application_BeginRequest(Object sender, EventArgs e)
    {        
        CacheTimer registTimer = new CacheTimer();
        registTimer.RegistCacheTimmer();        
    }
</pre>
<p>&nbsp;</p>
<p>但是如果我们的任务在没有执行完毕，IIS进程崩溃或者服务器重启了，怎么办？我的建议是把任务写人文件（包括数据库），检查的时候直接检查任务文件就可以保证重启IIS进程，任务不丢失了。</p>
<p>&nbsp;</p>
<p>感谢《<a target="_blank" href="http://www.codeproject.com/KB/aspnet/ASPNETService.aspx">Simulate a Windows Service using ASP.NET to run scheduled jobs</a>》的作者提供此定时器的解决方法。</p>
<p><a href="http://www.goberl.com/userAshx/fileDownLoad.ashx?fn=CacheTimer.rar" target="_blank">Goberl缓存时钟源码下载</a><br />
<br />
<br />
&nbsp;</p>]]>	</description>	<pubDate>2009-10-8 1:47:22</pubDate>	<category><![CDATA[Dev]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item60.aspx</guid></item><item>	<title><![CDATA[ASP.NET如何实现多线程]]></title>	<link><![CDATA[http://www.goberl.com/archive/item59.aspx]]></link>	<description><![CDATA[<p>上次做了个东西，用了多线程，现总结如下。</p>
<p>使用多线程是为了提高CPU的利用率，即在在相同的时间里面做更多的事情(但前提是系统资源没有完全耗尽），ASP.NET中使用多线程可以加快页面在服务器端的生成速度。一般页面生成过程中花费时间最多的是数据库查询阶段，如果你的页面有10个查询，不使用多线程的话，这10个查询将是串行执行的&mdash;&mdash;即依次执行每一个查询。如果使用多线程，将可以使这10个查询几乎同时执行。这显然会提高页面的生成速度。<br />
在网上搜索了些许帖子说在IIS进程中使用多线程是不稳定的，可我经过实践却发现ASP.NET使用多线程也没出啥问题。不过在ASP.NET中使用多线程得注意一些地方，不然确实是不稳定，甚至是行不通的。比如<strong>不能在多线程中使用HttpContext</strong>下的任何方法和属性，这就包括<span style="color: rgb(128, 128, 0);">Cookie</span>、<span style="color: rgb(128, 128, 0);">Session</span>、<span style="color: rgb(128, 128, 0);">Response</span>、<span style="color: rgb(128, 128, 0);">Request</span>、<span style="color: rgb(128, 128, 0);">Application</span>等等，当使用这些方法或者属性的时候,IIS进程将会直接崩溃。更要注意的是，由于多线程与页面的加载（Load）是异步执行的，<strong>必须让这些创建的线程在Load执行完之前同步</strong>，不然可能导致数据没有加载成功。 可能会有人问HttpContext等都被限制了，页面中还能做什么呢？我们完全可以把创建的线程与页面主体隔开，把需要的数据先在页面主体中获取，然后直接传入到创建的线程中就可解决。话不多说，具体如何，请看下文。</p>
<p>假设某个页面中有2个SQL查询，一个是根据Url传递来的参数P确定当前页的内容，另一个查询是显示所有分类。第一个查询语句需要用到<span style="color: rgb(128, 128, 0);">Request.QueryString</span>获取P传递来的页码，第二个查询语句则可直接写SQL语句。<br />
假设第一个查询语句如：<span style="color: rgb(128, 128, 0);">SELECT * FROM Archives WHERE Page=</span><span style="color: rgb(0, 0, 255);">传递的页码</span><br />
假设第二个查询语句如：<span style="color: rgb(128, 128, 0);">SELECT * FROM Category</span></p>
<p>我们先创建一个类，用于接受参数P和数据绑定控件ID(此处使用Repeater控件绑定数据),此类能够把SQL语句查询的结果绑定到数据控件(Repeater)中。</p>
<p>
  <pre id='CodecSharp0' class='CodecSharp'><a href='javascript:void(0);' onclick='copyCodeByID(0)'>复制代码</a>
<span class='code-keyword'>public</span> <span class='code-keyword'>class</span>BindData
{
    <span class='code-keyword'>private</span> int currentPage = 1;
    <span class='code-keyword'>private</span> Repeater rpID;

    <span class='code-keyword'>public</span> BindData(Repeater rpID)
    {
        <span class='code-keyword'>this</span>.rpID = rpID;
    }
    <span class='code-keyword'>public</span> BindData(Repeater rpID,int page)
    {
        <span class='code-keyword'>this</span>.rpID = rpID;
        <span class='code-keyword'>this</span>.currentPage = page;
    }   
    

    <span class='code-keyword'>public</span> <span class='code-keyword'>void</span> BindCategory()
    {
        <span class='code-keyword'>string</span> strSql=<span class='code-str'>&quot;SELECT * FROM Category&quot;</span>;
        <span class='code-keyword'>this</span>.BindDataToRepeater(strSql, <span class='code-keyword'>this</span>.rpID);

    }

    <span class='code-keyword'>public</span> <span class='code-keyword'>void</span> BindArchive()
    {
        <span class='code-keyword'>string</span> strSql = <span class='code-keyword'>string</span>.Format(<span class='code-str'>&quot;SELECT * FROM Archives WHERE Page={0}&quot;</span>,<span class='code-keyword'>this</span>.currentPage);
        <span class='code-keyword'>this</span>.BindDataToRepeater(strSql, <span class='code-keyword'>this</span>.rpID);
    }

    <span class='code-keyword'>private</span> <span class='code-keyword'>void</span> BindDataToRepeater(<span class='code-keyword'>string</span> strSql, Repeater rp)
    {
        <span class='code-keyword'>if</span> (rp == <span class='code-keyword'>null</span>) <span class='code-keyword'>return</span>;
        SqlConnection conn = <span class='code-keyword'>new</span> SqlConnection(<span class='code-str'>&quot;data source=数据服务器地址;User ID=用户名;pwd=密码;Initial Catalog=数据库名&quot;</span>);
        SqlCommand cmd = <span class='code-keyword'>new</span> SqlCommand(strSql, conn);
        SqlDataReader dtr;
        <span class='code-keyword'>try</span>

        {
            conn.Open();
            dtr = cmd.ExecuteReader();
            controlID.DataSource = rp;
            controlID.DataBind();
            <span class='code-keyword'>if</span> (!dtr.IsClosed)
                dtr.Close();
        }
        <span class='code-keyword'>catch</span> { }
        <span class='code-keyword'>finally</span>
        {
            cmd.Dispose();
            <span class='code-keyword'>if</span> (conn.State = ConnectionState.Open)
                conn.Close();
        }
 
    }
}
</pre>


</p>
<ol>
    <li>上面创建的<span style="color: rgb(128, 128, 0);">BindData</span>类中有2个构造函数，分别用于绑定分类、绑定Arhive的不同形式。如果使用其他数据绑定控件则可进行相应修改；</li>
    <li>创建了1个私有方法<span style="color: rgb(128, 128, 0);">BindDataToRepeater</span>用于把对应的SQL语句查询的结果绑定到对应的Repeater控件上。同时在此方法中使用了<span style="color: rgb(128, 128, 0);">SqlDataReader</span>，以提高绑定数据的速度。如果你使用了数据工厂可修改<span style="color: rgb(128, 128, 0);">BindDataToRepeater</span>中的具体实现过程；</li>
    <li>2个共有方法<span style="color: rgb(128, 128, 0);">BindCategory</span>和<span style="color: rgb(128, 128, 0);">BindArchive</span>分别用于创建不同SQL语句、设置Repater的ID；</li>
    <li>同时需要引入<span style="color: rgb(128, 128, 0);">System.Web.UI</span>、<span style="color: rgb(128, 128, 0);">System.Web.UI.HtmlControls</span>、<span style="color: rgb(128, 128, 0);">System.Data.SqlClient</span>3个必要的命名空间。</li>
</ol>
<p>值得注意的是在<span style="color: rgb(128, 128, 0);">BindDataToRepeater</span>方法中使用了try..catch语句，但并没有在catch块中做任何事情，为什么我们用try.catch却不在catch块中做点什么事情呢，不是多此一举吗？<strong>使用try..catch是为了防止在执行BindDataToRepeater时抛出异常，若此处出现异常且此方法是在多线程中执行的，将会导致IIS进程崩溃，进而影响其他页面的正常执行</strong>，故而用try...catch防止<span style="color: rgb(128, 128, 0);">BindDataToRepeater</span>抛出错误。</p>
<p>我们之所以为数据绑定创建一个类，是为了提高内存利用率，当数据加载（Load）完毕的时候，为这个类创建的实例就会销毁。我们也可以通过在页面中创建几个全局变量来实现。但我还是建议以类的形式传递数据而不是使用全局变量。下面，我们开始在页面的Load中创建线程了。首先你需要在页面中引入<span style="color: rgb(128, 128, 0);">System.Threading</span>命名空间。</p>
<p>
<pre id='CodecSharp0' class='CodecSharp'><a href='javascript:void(0);' onclick='copyCodeByID(0)'>复制代码</a>
<span class='code-keyword'>protected</span> <span class='code-keyword'>void</span> Page_Load(<span class='code-keyword'>object</span> sender, EventArgs e)
    {
        <span class='code-keyword'>if</span> (!IsPostBack)
        {
            int Page = 1;
            <span class='code-keyword'>if</span>(Request.QueryString[<span class='code-str'>&quot;p&quot;</span>]!=<span class='code-keyword'>null</span>)
                Page = Convert.ToInt32(Request.QueryString[<span class='code-str'>&quot;p&quot;</span>]);

            BindData LoadArchives = <span class='code-keyword'>new</span> BindData(rpArhive,Page);  
            Thread thArhives=<span class='code-keyword'>new</span> Thread(<span class='code-keyword'>new</span> ThreadStart(LoadArchives.BindArchive));  
            thArhives.Start();
      
            BindData LoadCategory=<span class='code-keyword'>new</span> BindData(rpCategory);
            Thread thCategory = <span class='code-keyword'>new</span> Thread(<span class='code-keyword'>new</span> ThreadStart(LoadCategory.BindCategory));
            thCategory.Start();

            <span class='code-note'>//进行页面的其他非数据绑定操作



</span>            thArhives.Join();
            thCategory.Join();
           
            

 
        }
    }
</pre>

</p>
<p>上面的代码显示在<span style="color: rgb(128, 128, 0);">!IsPostBack</span>状态下绑定数据。利用<span style="color: rgb(128, 128, 0);">Request.QueryString</span>获取了当前页码，并创建了<span style="color: rgb(128, 128, 0);">BindData</span>的2个实例<span style="color: rgb(128, 128, 0);">LoadArchives</span>、<span style="color: rgb(128, 128, 0);">LoadCategory</span>，通过<span style="color: rgb(128, 128, 0);"> <strong>Thread thArhives=new Thread(new ThreadStart(LoadArchives.BindArchive))</strong></span>为绑定Arhice创建线程，通过<span style="color: rgb(128, 128, 0);"><strong>Thread thCategory = new Thread(new ThreadStart(LoadCategory.BindCategory))</strong></span>为绑定分类创建线程，同时调用<span style="color: rgb(128, 128, 0);">Thread</span>的<span style="color: rgb(128, 128, 0);">Start</span>方法使2个线程进入执行状态。最后，在Load的最下面用Thread的<span style="color: rgb(128, 128, 0);">Join</span>方法使创建的2个线程与页面加载同步。<br />
值得注意的是，<strong>Join方法是必须的，如果不使用，可能导致创建的线程还未把数据完全绑定到Repeater上，Load就已经执行完毕，若如此页面上将没有任何数据。同时调用Start的代码行应尽量早，调用Join的代码行都应尽量迟&mdash;&mdash;尽量放在Page_Load代码段的末尾</strong>，这样才能达到多线程的目的，若你每调用一个Start马上调用Join，其实质和没有使用多线程的效果是一样的。Join在MSND上的解释是：<strong>在继续执行标准的 COM 和 SendMessage 消息泵处理期间，阻塞调用线程，直到某个线程终止为止</strong>。</p>
<p>只要设置好ASPX页面Repeater的绑定项，数据就可成功加载了。上面仅仅展示了2个SQL语句的查询，如果你有10个或者更多的SQL查询，在Page_Load中创建10个线程，让他们异步执行，最后用<span style="color: rgb(128, 128, 0);">Join</span>同步到Load，是一个提高性能的不错方法。</p>
<p><strong>本文由Goberl理解实践，但个人能力有限，若有错误，望请指教！</strong><br />
<br />
<br />
&nbsp;</p>]]>	</description>	<pubDate>2009-10-7 0:04:58</pubDate>	<category><![CDATA[Dev]]></category>	<author><![CDATA[Goberl]]></author>	<guid>http://www.goberl.com/archive/item59.aspx</guid></item></channel></rss>
