<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_eaglet</title><subtitle type="text">本博专注于基于微软技术的搜索相关技术</subtitle><id>http://feed.cnblogs.com/blog/u/26415/rss</id><updated>2011-12-05T06:20:09Z</updated><author><name>eaglet</name><uri>http://www.cnblogs.com/eaglet/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/eaglet/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/26415/rss"/><entry><id>http://www.cnblogs.com/eaglet/archive/2011/12/05/2276668.html</id><title type="text">C# 程序自动批量生成 google maps 的KML文件</title><summary type="text">google maps 的 KML 文件可以用于静态的地图标注，在某些应用中，我们手上往往有成百上千个地址，我们需要把这些地址和描述批量标注到 google maps 上去，如果手工来做，太耗时间，在这里我写了一个程序批量来生成这个 KML 文件。</summary><published>2011-12-05T04:59:00Z</published><updated>2011-12-05T04:59:00Z</updated><author><name>eaglet</name><uri>http://www.cnblogs.com/eaglet/</uri></author><link rel="alternate" href="http://www.cnblogs.com/eaglet/archive/2011/12/05/2276668.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/eaglet/archive/2011/12/05/2276668.html"/><content type="html">&lt;p&gt;google maps 的 KML 文件可以用于静态的地图标注，在某些应用中，我们手上往往有成百上千个地址，我们需要把这些地址和描述批量标注到 google maps 上去，如果手工来做，太耗时间，在这里我写了一个程序批量来生成这个 KML 文件。&lt;/p&gt; &lt;p&gt;首先看一下 KML 文件的格式：&lt;/p&gt;&lt;pre &gt;&lt;span &gt;&amp;lt;?&lt;/span&gt;&lt;span &gt;xml&lt;/span&gt; &lt;span &gt;version&lt;/span&gt;&lt;span &gt;="1.0"&lt;/span&gt; &lt;span &gt;encoding&lt;/span&gt;&lt;span &gt;="UTF-8"&lt;/span&gt;?&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;kml&lt;/span&gt; &lt;span &gt;xmlns&lt;/span&gt;&lt;span &gt;="http://www.google.com/earth/kml/2"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;Document&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;kml_sample2.kml&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;Style&lt;/span&gt; &lt;span &gt;id&lt;/span&gt;&lt;span &gt;="red"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;IconStyle&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;Icon&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
          &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;href&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;http://www.google.com/intl/en_us/mapfiles/ms/icons/red-dot.png&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;href&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Icon&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;IconStyle&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Style&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;Style&lt;/span&gt; &lt;span &gt;id&lt;/span&gt;&lt;span &gt;="green"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;IconStyle&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;Icon&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
          &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;href&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;http://www.google.com/intl/en_us/mapfiles/ms/icons/green-dot.png&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;href&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Icon&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;IconStyle&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Style&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;Style&lt;/span&gt; &lt;span &gt;id&lt;/span&gt;&lt;span &gt;="blue"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;IconStyle&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;Icon&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
          &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;href&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;http://www.google.com/intl/en_us/mapfiles/ms/icons/blue-dot.png&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;href&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
        &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Icon&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;IconStyle&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Style&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;Placemark&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;Google Inc.&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;description&lt;/span&gt;&lt;span &gt;&amp;gt;&amp;lt;!&lt;/span&gt;[CDATA[&#xD;
      Google Inc.&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;br&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      1600 Amphitheatre Parkway&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;br&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      Mountain View, CA 94043&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;br&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      Phone: +1 650-253-0000&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;br&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      Fax: +1 650-253-0001&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;br&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;p&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;Home page: &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;a&lt;/span&gt; &lt;span &gt;href&lt;/span&gt;&lt;span &gt;="http://www.google.com"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;www.google.com&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;a&lt;/span&gt;&lt;span &gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;p&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    ]]&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;description&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;styleUrl&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;#red&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;styleUrl&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt; &#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;Point&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;coordinates&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;-122.0841430, 37.4219720, 0&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;coordinates&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Point&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
  &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Placemark&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
  &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;Placemark&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;Yahoo! Inc.&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;description&lt;/span&gt;&lt;span &gt;&amp;gt;&amp;lt;!&lt;/span&gt;[CDATA[&#xD;
      Yahoo! Inc.&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;br&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      701 First Avenue&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;br&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      Sunnyvale, CA 94089&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;br&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      Tel: (408) 349-3300&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;br&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      Fax: (408) 349-3301&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;br&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;p&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;Home page: &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;a&lt;/span&gt; &lt;span &gt;href&lt;/span&gt;&lt;span &gt;="http://yahoo.com"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;http://yahoo.com&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;a&lt;/span&gt;&lt;span &gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;p&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      ]]&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;description&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;styleUrl&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;#green&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;styleUrl&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt; &#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;Point&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
      &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;coordinates&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;-122.0250403,37.4163228&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;coordinates&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Point&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
  &lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Placemark&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&#xD;
&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Document&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&#xD;
&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;kml&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;这个是一个典型的用于google maps 的 KML 文件，（注意不同应用的KML 格式会有所不同，比如 google earth 的 kml 格式就复杂得多)&lt;/p&gt;&#xD;
&lt;p&gt;从这个kml 文件格式来看，其实它就是一个 xml 文件，我们只要自动生成这个文件中各个元素的信息就可以得到这个xml&amp;nbsp; 文件。这里其实最大的问题是如何自动通过地址获取经纬度坐标。值得庆幸的是 google 提供了这方面的 api 函数。google api 获取地理坐标的官方例子见：&lt;a href="http://code.google.com/p/geocodingapi/" target="_blank"&gt;geocodingapi&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我的实现稍微复杂一些，因为我需要在函数中为不同的位置自动分配颜色&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;   1:  &lt;/span&gt;        &lt;span &gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;        &lt;span &gt;/// Generate placemark by address description&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   3:  &lt;/span&gt;        &lt;span &gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;        &lt;span &gt;/// &amp;lt;param name="addrDescription"&amp;gt;address and description&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   5:  &lt;/span&gt;        &lt;span &gt;/// &amp;lt;returns&amp;gt;if no matched, return false&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   6:  &lt;/span&gt;        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;bool&lt;/span&gt; Generate(AddressDescription addrDescription)&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   7:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   8:  &lt;/span&gt;            _LastErrorOrWarning = &lt;span &gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;   9:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  10:  &lt;/span&gt;            Thread.Sleep(DelayInMs);&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  11:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  12:  &lt;/span&gt;            List&amp;lt;GeographicCoordinate&amp;gt; coordinates = Geocoding.Geocode(addrDescription.Address);&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  13:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  14:  &lt;/span&gt;            &lt;span &gt;if&lt;/span&gt; (coordinates.Count == 0)&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  15:  &lt;/span&gt;            {&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  16:  &lt;/span&gt;                _LastErrorOrWarning = &lt;span &gt;string&lt;/span&gt;.Format(&lt;span &gt;"Address:{0}, Description:{1} does not find the coordinates, please make sure the address is correctly."&lt;/span&gt;,&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  17:  &lt;/span&gt;                    addrDescription.Address, addrDescription.Description);&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  18:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  19:  &lt;/span&gt;                &lt;span &gt;return&lt;/span&gt; &lt;span &gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  20:  &lt;/span&gt;            }&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  21:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  22:  &lt;/span&gt;            &lt;span &gt;if&lt;/span&gt; (coordinates.Count &amp;gt; 1)&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  23:  &lt;/span&gt;            {&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  24:  &lt;/span&gt;                _LastErrorOrWarning = &lt;span &gt;string&lt;/span&gt;.Format(&lt;span &gt;"Address:{0}, Description:{1} has more than one coordinates."&lt;/span&gt;,&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  25:  &lt;/span&gt;                    addrDescription.Address, addrDescription.Description);&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  26:  &lt;/span&gt;            }&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  27:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  28:  &lt;/span&gt;            &lt;span &gt;string&lt;/span&gt; colorId = Colors[_ColorIndex];&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  29:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  30:  &lt;/span&gt;            _ColorIndex++;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  31:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  32:  &lt;/span&gt;            &lt;span &gt;if&lt;/span&gt; (_ColorIndex &amp;gt;= Colors.Count)&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  33:  &lt;/span&gt;            {&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  34:  &lt;/span&gt;                _ColorIndex = 0;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  35:  &lt;/span&gt;            }&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  36:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  37:  &lt;/span&gt;            _Kml.Document.Add(&lt;span &gt;new&lt;/span&gt; Placemark(addrDescription.Address, addrDescription.Description, colorId,&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  38:  &lt;/span&gt;                coordinates[0].Latitude, coordinates[0].Longitude));&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  39:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  40:  &lt;/span&gt;            &lt;span &gt;return&lt;/span&gt; &lt;span &gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span &gt;  41:  &lt;/span&gt;        }&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;p&gt;第32行有个bug，应该是 &amp;gt;=&amp;nbsp; ，我原来写成 &amp;gt; 了，博客中我改过来了，源码我就不改了。 &lt;br /&gt;&lt;/p&gt;&lt;p&gt;如上代码，第12行就是通过GeocodingApi 获取指定地址的物理坐标，由于有时候获取不到坐标，有时候由于地址不确切，有多个坐标，所以我加了一个错误和警告的属性，用于调用者得到相关的信息。&lt;/p&gt;&#xD;
&lt;p&gt;_Kml 这个对象是一个 Kml 类的实例，这个类用于生成 KML 文件结构，并可以保存到KML文件中。这个类在后面介绍。&lt;/p&gt;&#xD;
&lt;p&gt;下面的 _Color 部分是自动的顺序分配标注点的颜色，我为了省事，在代码中写死了4种颜色，你也可以修改代码增加颜色或其他图标。&lt;/p&gt;&#xD;
&lt;p&gt;标注颜色这里其实还有一个问题，就是如果让相邻的节点显示不同颜色，这个算法比较复杂了，我没有实现，各位如果有兴趣可以思考一下这个怎么做。&lt;/p&gt;&#xD;
&lt;p&gt;好了，最大的问题解决了，剩下就是写 xml&amp;nbsp; 文件了，这个很简单，我就不深入讲了，直接把代码贴出来。&lt;/p&gt;&lt;pre &gt;&lt;span &gt;using&lt;/span&gt; System;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Collections.Generic;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Linq;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Text;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Xml;&#xD;
&lt;span &gt;using&lt;/span&gt; System.Xml.Serialization;&#xD;
&lt;span &gt;using&lt;/span&gt; System.IO;&#xD;
&#xD;
&lt;span &gt;namespace&lt;/span&gt; GenerateKML&#xD;
{&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; Placemark&#xD;
    {&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; KMLPoint&#xD;
        {&#xD;
            &lt;span &gt;public&lt;/span&gt; KMLPoint()&#xD;
            {&#xD;
            }&#xD;
&#xD;
            &lt;span &gt;public&lt;/span&gt; KMLPoint(&lt;span &gt;double&lt;/span&gt; latitude, &lt;span &gt;double&lt;/span&gt; longitude)&#xD;
            {&#xD;
                SetCoordinates(latitude, longitude);&#xD;
            }&#xD;
&#xD;
            &lt;span &gt;private&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; _coordinates;&#xD;
&#xD;
            &lt;span &gt;public&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; SetCoordinates(&lt;span &gt;double&lt;/span&gt; latitude, &lt;span &gt;double&lt;/span&gt; longitude)&#xD;
            {&#xD;
                _coordinates = longitude.ToString() + &lt;span &gt;","&lt;/span&gt; + latitude.ToString();&#xD;
            }&#xD;
&#xD;
            &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; coordinates&#xD;
            {&#xD;
                get&#xD;
                {&#xD;
                    &lt;span &gt;return&lt;/span&gt; _coordinates;&#xD;
                }&#xD;
&#xD;
                set&#xD;
                {&#xD;
                    _coordinates = &lt;span &gt;value&lt;/span&gt;;&#xD;
                }&#xD;
            }&#xD;
        }&#xD;
&#xD;
        [XmlElement(&lt;span &gt;"name"&lt;/span&gt;)]&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; Name { get; set; }&#xD;
&#xD;
        [XmlElement(&lt;span &gt;"description"&lt;/span&gt;)]&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; Description { get; set; }&#xD;
&#xD;
        [XmlElement(&lt;span &gt;"styleUrl"&lt;/span&gt;)]&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;string&lt;/span&gt; StyleUrl { get; set; }&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; KMLPoint Point { get; set; }&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; Placemark()&#xD;
        {&#xD;
        }&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; Placemark(&lt;span &gt;string&lt;/span&gt; name, &lt;span &gt;string&lt;/span&gt; description, &lt;span &gt;string&lt;/span&gt; styleUrl,&#xD;
            &lt;span &gt;double&lt;/span&gt; latitude, &lt;span &gt;double&lt;/span&gt; longitude)&#xD;
        {&#xD;
            Name = name;&#xD;
            Description = description;&#xD;
            StyleUrl = styleUrl;&#xD;
&#xD;
            Point = &lt;span &gt;new&lt;/span&gt; KMLPoint(latitude, longitude);&#xD;
        }&#xD;
&#xD;
    }&#xD;
&#xD;
    &lt;span &gt;public&lt;/span&gt; &lt;span &gt;class&lt;/span&gt; kml&#xD;
    {&#xD;
        [XmlIgnore]&#xD;
        &lt;span &gt;string&lt;/span&gt; Name { get; set; }&#xD;
&#xD;
&#xD;
        List&amp;lt;Placemark&amp;gt; _Placemarks = &lt;span &gt;new&lt;/span&gt; List&amp;lt;Placemark&amp;gt;();&#xD;
&#xD;
        [XmlArray()]&#xD;
        &lt;span &gt;public&lt;/span&gt; List&amp;lt;Placemark&amp;gt; Document&#xD;
        {&#xD;
            get&#xD;
            {&#xD;
                &lt;span &gt;return&lt;/span&gt; _Placemarks;&#xD;
            }&#xD;
&#xD;
            set&#xD;
            {&#xD;
                _Placemarks = &lt;span &gt;value&lt;/span&gt;;&#xD;
            }&#xD;
        }&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; kml()&#xD;
        {&#xD;
        }&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; kml(&lt;span &gt;string&lt;/span&gt; name)&#xD;
        {&#xD;
            Name = name;&#xD;
        }&#xD;
&#xD;
        &lt;span &gt;private&lt;/span&gt; XmlNode GetColorStyle(XmlDocument xmlDoc,  &lt;span &gt;string&lt;/span&gt; color)&#xD;
        {&#xD;
            XmlNode style = xmlDoc.CreateNode(XmlNodeType.Element, &lt;span &gt;"Style"&lt;/span&gt;, &lt;span &gt;""&lt;/span&gt;);&#xD;
            XmlAttribute attr = style.OwnerDocument.CreateAttribute(&lt;span &gt;"id"&lt;/span&gt;);&#xD;
            attr.Value = color;&#xD;
            style.Attributes.Append(attr);&#xD;
&#xD;
            XmlNode iconStyle = xmlDoc.CreateNode(XmlNodeType.Element, &lt;span &gt;"IconStyle"&lt;/span&gt;, &lt;span &gt;""&lt;/span&gt;);&#xD;
            XmlNode icon = xmlDoc.CreateNode(XmlNodeType.Element, &lt;span &gt;"Icon"&lt;/span&gt;, &lt;span &gt;""&lt;/span&gt;);&#xD;
            XmlNode href = xmlDoc.CreateNode(XmlNodeType.Element, &lt;span &gt;"href"&lt;/span&gt;, &lt;span &gt;""&lt;/span&gt;);&#xD;
            href.InnerText = &lt;span &gt;string&lt;/span&gt;.Format(&lt;span &gt;"http://www.google.com/intl/en_us/mapfiles/ms/icons/{0}-dot.png"&lt;/span&gt;,&#xD;
                color);&#xD;
            &#xD;
            &#xD;
            style.AppendChild(iconStyle);&#xD;
            iconStyle.AppendChild(icon);&#xD;
            icon.AppendChild(href);&#xD;
&#xD;
            &lt;span &gt;return&lt;/span&gt; style;&#xD;
        }&#xD;
&#xD;
&#xD;
        &lt;span &gt;public&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; SaveToFile(&lt;span &gt;string&lt;/span&gt; xml)&#xD;
        {&#xD;
            &lt;span &gt;using&lt;/span&gt; (FileStream fs = &lt;span &gt;new&lt;/span&gt; FileStream(xml, FileMode.Create, FileAccess.ReadWrite))&#xD;
            {&#xD;
                &lt;span &gt;using&lt;/span&gt; (StreamWriter sw = &lt;span &gt;new&lt;/span&gt; StreamWriter(fs, System.Text.Encoding.UTF8))&#xD;
                {&#xD;
                    XmlSerializer serializer = &lt;span &gt;new&lt;/span&gt; XmlSerializer(&lt;span &gt;this&lt;/span&gt;.GetType());&#xD;
                    serializer.Serialize(sw, &lt;span &gt;this&lt;/span&gt;);&#xD;
                }&#xD;
            }&#xD;
&#xD;
&#xD;
            XmlDocument xmlDoc = &lt;span &gt;new&lt;/span&gt; XmlDocument();&#xD;
            xmlDoc.Load(xml);&#xD;
            xmlDoc.CreateXmlDeclaration(&lt;span &gt;"1.0"&lt;/span&gt;, &lt;span &gt;"utf-8"&lt;/span&gt;, &lt;span &gt;null&lt;/span&gt;);&#xD;
&#xD;
            XmlNode documentNode = xmlDoc.SelectSingleNode(&lt;span &gt;@"/kml/Document"&lt;/span&gt;);&#xD;
&#xD;
            XmlNode nameNode = xmlDoc.CreateNode(XmlNodeType.Element, &lt;span &gt;"name"&lt;/span&gt;, &lt;span &gt;""&lt;/span&gt;);&#xD;
            nameNode.InnerText = &lt;span &gt;this&lt;/span&gt;.Name;&#xD;
&#xD;
            XmlNode placeMarkNode = documentNode.FirstChild;&#xD;
            documentNode.InsertBefore(nameNode, placeMarkNode);&#xD;
&#xD;
            documentNode.InsertBefore(GetColorStyle(xmlDoc, &lt;span &gt;"red"&lt;/span&gt;), placeMarkNode);&#xD;
            documentNode.InsertBefore(GetColorStyle(xmlDoc, &lt;span &gt;"green"&lt;/span&gt;), placeMarkNode);&#xD;
            documentNode.InsertBefore(GetColorStyle(xmlDoc, &lt;span &gt;"blue"&lt;/span&gt;), placeMarkNode);&#xD;
            documentNode.InsertBefore(GetColorStyle(xmlDoc, &lt;span &gt;"yellow"&lt;/span&gt;), placeMarkNode);&#xD;
&#xD;
            XmlNode kmlNode = xmlDoc.SelectSingleNode(&lt;span &gt;@"/kml"&lt;/span&gt;);&#xD;
&#xD;
            XmlAttribute attr = kmlNode.OwnerDocument.CreateAttribute(&lt;span &gt;"xmlns"&lt;/span&gt;);&#xD;
            attr.Value = &lt;span &gt;"http://earth.google.com/kml/2.0"&lt;/span&gt;;&#xD;
&#xD;
            kmlNode.Attributes.Append(attr);&#xD;
&#xD;
            xmlDoc.Save(xml);&#xD;
        }&#xD;
    }&#xD;
&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;下面看一下调用的方法，使用者如果不想仔细研究细节，那就关注这个就可以了，调用方法非常简单&lt;/p&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;   1:  &lt;/span&gt;        &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; Main(&lt;span &gt;string&lt;/span&gt;[] args)&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;   2:  &lt;/span&gt;        {&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;   3:  &lt;/span&gt;            Generator kmlGenerator = &lt;span &gt;new&lt;/span&gt; Generator(&lt;span &gt;"Test"&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;   4:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;   5:  &lt;/span&gt;            kmlGenerator.Generate(&lt;span &gt;new&lt;/span&gt; AddressDescription(&lt;span &gt;"1600 Amphitheatre Parkway, Mountain View, CA 94043"&lt;/span&gt;,&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;   6:  &lt;/span&gt;                &lt;span &gt;"Google"&lt;/span&gt;));&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;   7:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;   8:  &lt;/span&gt;            &lt;span &gt;if&lt;/span&gt; (!&lt;span &gt;string&lt;/span&gt;.IsNullOrEmpty(kmlGenerator.LastErrorOrWarning))&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;   9:  &lt;/span&gt;            {&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  10:  &lt;/span&gt;                Console.WriteLine(kmlGenerator.LastErrorOrWarning);&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  11:  &lt;/span&gt;            }&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  12:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  13:  &lt;/span&gt;            kmlGenerator.Generate(&lt;span &gt;new&lt;/span&gt; AddressDescription(&lt;span &gt;"1 Microsoft Way, Redmond, WA 98052"&lt;/span&gt;,&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  14:  &lt;/span&gt;                &lt;span &gt;"Microsoft"&lt;/span&gt;));&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  15:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  16:  &lt;/span&gt;            &lt;span &gt;if&lt;/span&gt; (!&lt;span &gt;string&lt;/span&gt;.IsNullOrEmpty(kmlGenerator.LastErrorOrWarning))&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  17:  &lt;/span&gt;            {&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  18:  &lt;/span&gt;                Console.WriteLine(kmlGenerator.LastErrorOrWarning);&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  19:  &lt;/span&gt;            }&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  20:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  21:  &lt;/span&gt;            kmlGenerator.Generate(&lt;span &gt;new&lt;/span&gt; AddressDescription(&lt;span &gt;"1601 S. California Ave., Palo Alto, CA 95304"&lt;/span&gt;,&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  22:  &lt;/span&gt;                &lt;span &gt;"Facebook"&lt;/span&gt;));&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  23:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  24:  &lt;/span&gt;            &lt;span &gt;if&lt;/span&gt; (!&lt;span &gt;string&lt;/span&gt;.IsNullOrEmpty(kmlGenerator.LastErrorOrWarning))&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  25:  &lt;/span&gt;            {&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  26:  &lt;/span&gt;                Console.WriteLine(kmlGenerator.LastErrorOrWarning);&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  27:  &lt;/span&gt;            }&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  28:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  29:  &lt;/span&gt;            kmlGenerator.Generate(&lt;span &gt;new&lt;/span&gt; AddressDescription(&lt;span &gt;"701 First Ave, Sunnyvale, CA 94089"&lt;/span&gt;,&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  30:  &lt;/span&gt;                &lt;span &gt;"Yahoo"&lt;/span&gt;));&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  31:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  32:  &lt;/span&gt;            &lt;span &gt;if&lt;/span&gt; (!&lt;span &gt;string&lt;/span&gt;.IsNullOrEmpty(kmlGenerator.LastErrorOrWarning))&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  33:  &lt;/span&gt;            {&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  34:  &lt;/span&gt;                Console.WriteLine(kmlGenerator.LastErrorOrWarning);&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  35:  &lt;/span&gt;            }&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  36:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  37:  &lt;/span&gt;            kmlGenerator.Save(&lt;span &gt;"test.kml"&lt;/span&gt;);&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  38:  &lt;/span&gt;        }&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;span &gt;  39:  &lt;/span&gt;    }&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;第三行，实例化 KML 生成器，并指定一个名字，这个名字对于 kml 文档中的 name 字段。&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;第五行，在kml 文件中标注 google 总部的地址&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;第八行，判断是否有最新的错误，每次执行第五行的Generate 方法，会将最新错误清空，所以这里永远是得到最近一次调用 Generate 方法的错误或警告。&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;后面以此类推了。&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;最后 Save 到一个kml文件中就OK了。&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;最后，我们可以把这个 kml 文件导入到我们自己创建的 google map 中。这个在 google maps 里面有相应的导入功能，这里就不介绍了。&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;完整源码下载&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;a href="http://files.cnblogs.com/eaglet/GenerateKML.zip"&gt;完整源码&lt;/a&gt;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;注意源码中 app.config 文件中&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;div &gt;&lt;pre &gt;&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;key&lt;/span&gt;&lt;span &gt;="GeocodingApi.Key"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="google api key"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&#xD;
    &lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;add&lt;/span&gt; &lt;span &gt;key&lt;/span&gt;&lt;span &gt;="GeocodingApi.Url"&lt;/span&gt; &lt;span &gt;value&lt;/span&gt;&lt;span &gt;="http://maps.google.com/maps/geo?"&lt;/span&gt; &lt;span &gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;p&gt;GeocodingApi.key 这里要填写你自己的 google api key，你可以在 google&amp;nbsp; 网站上获取，地址如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a title="http://code.google.com/apis/maps/signup.html" href="http://code.google.com/apis/maps/signup.html"&gt;http://code.google.com/apis/maps/signup.html&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;font face="Consolas" size="2"&gt;&lt;/font&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;div &gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&lt;img src="http://www.cnblogs.com/eaglet/aggbug/2276668.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/eaglet/archive/2011/12/05/2276668.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/eaglet/archive/2011/11/01/2231021.html</id><title type="text">通过 Windows 7 共享上网</title><summary type="text">要实现多台机器共享上网通常有两种方法，一种是通过路由器共享上网，一种是通过软网关共享上网。在某些情况下，比如要通过3G，或4G无线网卡共享上网，我们需要特殊的3G或4G无线路由器才能共享，在没有这种路由器的情况下，我们只能通过软件共享上网。windows 7 提供了这样的共享功能，而且配置非常简单。</summary><published>2011-11-01T01:41:00Z</published><updated>2011-11-01T01:41:00Z</updated><author><name>eaglet</name><uri>http://www.cnblogs.com/eaglet/</uri></author><link rel="alternate" href="http://www.cnblogs.com/eaglet/archive/2011/11/01/2231021.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/eaglet/archive/2011/11/01/2231021.html"/><content type="html">&lt;p&gt;要实现多台机器共享上网通常有两种方法，一种是通过路由器共享上网，一种是通过软网关共享上网。在某些情况下，比如要通过3G，或4G无线网卡共享上网，我们需要特殊的3G或4G无线路由器才能共享，在没有这种路由器的情况下，我们只能通过软件共享上网。windows 7 提供了这样的共享功能，而且配置非常简单。下面我就把我如何配置办公室的共享上网的步骤写下来，供大家参考。&lt;/p&gt;&#xD;
&lt;p&gt;在开始这篇文章之前，我先介绍一下我的网络环境。&lt;/p&gt;&#xD;
&lt;p&gt;办公室里面有一台台式电脑，操作系统是 windows 7 professional 64bit。 通过 4G 无线网卡上网，上网速度为 20Mbps(下行)/16Mbps(上行)。一台无线路由器，若干办公电脑和网络打印机。没有有线的上网线路。其实普通的 ADSL2+ 的下行速度在我们这里最高只能达到10Mbps，还不如 4G 无线网卡的速度快。注：中国大陆地区目前好像还没有开通4G无线网络，不过无所谓，电脑只要能上网就可以进行共享。&lt;/p&gt;&#xD;
&lt;p&gt;我的目标就是让所有的设备都通过4G无线网卡访问 internet.&lt;/p&gt;&#xD;
&lt;p&gt;首先考虑的是通过路由器来共享，但由于 4G 无线网络在澳大利亚刚刚开通才一个月，还没有相应的无线路由器，找到一个3G的无线路由器 NetComm 的 N3G002W。如下图所示：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/eaglet/201111/201111010940103830.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/eaglet/201111/201111010940145909.png" width="323" height="323" /&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;测试了一下，不支持4G无线网卡，只支持3G的，不过3G的无线网卡上网速度实在太慢了，放弃这个想法。&lt;/p&gt;&#xD;
&lt;p&gt;既然不能通过路由器共享，接下来就只能通过软网关来共享上网了。一开始我并不知道 windows 7 自带有类似的功能，在网上找了两个软网关，一个是WinRoute,这个软件是收费的，399美元，而且从网站说明上看，不支持 windows 7. 还有一个是 AnyRouter，这个软件有免费版本，但界面是中文的（公司里面只有我能看懂中文) ，而且从网站说明上看好像也不支持 windows 7。看来都不符合我的要求。还是 google 吧。一搜不要紧，发现windows 7 本身就自带 internet share 的功能，叫 ICS (Internet Connection Sharing)。 参见 &lt;a href="http://windows.microsoft.com/en-AU/windows-vista/Using-ICS-Internet-Connection-Sharing" target="_blank"&gt;Using ICS (Internet Connection Sharing)&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;下面就把我的设置步骤说明一下，很简单。&lt;/p&gt;&#xD;
&lt;p&gt;首先进入 Control Panel-&amp;gt;Network and Internet-&amp;gt;Network and Sharing Center，如下图&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/eaglet/201111/201111010940177498.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/eaglet/201111/201111010940212990.png" width="610" height="206" /&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;这里有个 Telstra Mobile 的网络适配器，这个就是我前面说的 4G 无线网卡的网络适配器，那个台式机就是通过这个无线网卡上网的。点圆圈里面那个蓝色链接再点 Properites(中文系统这里应该是 属性)。进入到这个网络适配器的属性配置。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/eaglet/201111/201111010940233872.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/eaglet/201111/201111010940269082.png" width="350" height="439" /&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;在属性设置中，选第二个tab-&amp;gt;Sharing （共享），然后将我红圈部分选中就可以了。下面有一个 Home networking connection 要选择一下，这个设置的意思是通过哪个网络适配器进行共享。通常情况下我们都是通过本地的以太网网卡进行共享，在这里我选择的是本地网络的网络适配器。&lt;/p&gt;&#xD;
&lt;p&gt;点OK后，会有个提示，说本地网络适配器的IP地址将被强行改为 192.168.137.1，这是因为要做软网关，需要一个固定IP地址，windows 7 就强行把这个地址固定在了192.168.137.1 上了。点确认，设置结束。&lt;/p&gt;&#xD;
&lt;p&gt;下面的工作就是配置路由器了。&lt;/p&gt;&#xD;
&lt;p&gt;路由器的链接方法是用直连网线连接路由器的LAN 口和上面那个 windows 7 的台式机的本地网卡。可能也可以连WAN 口，然后配置为级联，不过我没有试过。&lt;/p&gt;&#xD;
&lt;p&gt;路由器的配置方法如下：&lt;/p&gt;&#xD;
&lt;p&gt;首先路由器的IP网段要设置为 192.168.137.* 这个网段(当然也可以用级联)，直接改了路由器的本地IP地址为 192.168.137.2 ，这样网段就一致了。&lt;/p&gt;&#xD;
&lt;p&gt;然后就是配置网关和DNS 地址，这两个地址都设置为 192.168.137.1，即指向 windows 7 的软网关，如下图所示：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/eaglet/201111/201111010940277521.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/eaglet/201111/201111010940304225.png" width="473" height="176" /&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;有的路由器还要手工设置一下 DHCP 的地址范围，比如设置为 192.168.137.100 &amp;#8211; 192.168.137.254&lt;/p&gt;&#xD;
&lt;p&gt;配置好后，重启路由器。&lt;/p&gt;&#xD;
&lt;p&gt;打开我的笔记本电脑，用无线网卡连接无线路由器自动获取IP地址后，测试了一下，可以正常访问internet 了。至此配置结束。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/eaglet/aggbug/2231021.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/eaglet/archive/2011/11/01/2231021.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/eaglet/archive/2011/10/31/2230197.html</id><title type="text">正确理解 SqlConnection 的连接池机制</title><summary type="text">.net 中通过 SqlConnection 连接 sql server，我们会发现第一次连接时总是很耗时，但后面连接就很快，这个其实和SqlConnection 的连接池机制有关，正确的理解这个连接池机制，有助于我们编写高效的数据库应用程序。</summary><published>2011-10-31T05:44:00Z</published><updated>2011-10-31T05:44:00Z</updated><author><name>eaglet</name><uri>http://www.cnblogs.com/eaglet/</uri></author><link rel="alternate" href="http://www.cnblogs.com/eaglet/archive/2011/10/31/2230197.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/eaglet/archive/2011/10/31/2230197.html"/><content type="html">&lt;p&gt;作者: eaglet&lt;/p&gt;&#xD;
&lt;p&gt;转载请注明出处&lt;/p&gt;&#xD;
&lt;p&gt;.net 中通过 SqlConnection 连接 sql server，我们会发现第一次连接时总是很耗时，但后面连接就很快，这个其实和SqlConnection 的连接池机制有关，正确的理解这个连接池机制，有助于我们编写高效的数据库应用程序。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;很多人认为 SqlConnection 的连接是不耗时的，理由是循环执行 SqlConnection.Open 得到的平均时间几乎为0，但每次首次open 时，耗时又往往达到几个毫秒到几秒不等，这又是为什么呢？&lt;/p&gt;&#xD;
&lt;p&gt;首先我们看一下 MSDN 上的权威文档上是怎么说的&lt;/p&gt;&#xD;
&lt;p&gt;Connecting to a database server typically consists of several time-consuming steps. A physical channel such as a socket or a named pipe must be established, the initial handshake with the server must occur, the connection string information must be parsed, the connection must be authenticated by the server, checks must be run for enlisting in the current transaction, and so on.&lt;/p&gt;&#xD;
&lt;p&gt;以上摘自 &lt;a title="http://msdn.microsoft.com/en-us/library/8xx3tyca%28VS.80%29.aspx" href="http://msdn.microsoft.com/en-us/library/8xx3tyca%28VS.80%29.aspx"&gt;http://msdn.microsoft.com/en-us/library/8xx3tyca%28VS.80%29.aspx&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;也就是说物理连接建立时，需要做和服务器握手，解析连接字符串，授权，约束的检查等等操作，而物理连接建立后，这些操作就不会去做了。这些操作是需要一定的时间的。所以很多人喜欢用一个静态对象存储 SqlConnection 来始终保持物理连接，但采用静态对象时，多线程访问会带来一些问题，实际上，我们完全不需要这么做，因为 SqlConnection 默认打开了连接池功能，当程序 执行&amp;nbsp; SqlConnection.Close 后，物理连接并不会被立即释放，所以这才出现当循环执行 Open操作时，执行时间几乎为0.&lt;/p&gt;&#xD;
&lt;p&gt;下面我们先看一下不打开连接池时，循环执行 SqlConnection.Open 的耗时&lt;/p&gt;&lt;pre &gt;&lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; OpenWithoutPooling()&#xD;
        {&#xD;
            &lt;span &gt;string&lt;/span&gt; connectionString =&#xD;
                &lt;span &gt;"Data Source=192.168.10.2; Initial Catalog=News; Integrated Security=True;Pooling=False;"&lt;/span&gt;;&#xD;
&#xD;
            Stopwatch sw = &lt;span &gt;new&lt;/span&gt; Stopwatch();&#xD;
&#xD;
            sw.Start();&#xD;
            &lt;span &gt;using&lt;/span&gt; (SqlConnection conn =&#xD;
                &lt;span &gt;new&lt;/span&gt; SqlConnection(connectionString))&#xD;
            {&#xD;
                conn.Open();&#xD;
            }&#xD;
&#xD;
            sw.Stop();&#xD;
            Console.WriteLine(&lt;span &gt;"Without Pooling, first connection elapsed {0} ms"&lt;/span&gt;, sw.ElapsedMilliseconds);&#xD;
&#xD;
            sw.Reset();&#xD;
&#xD;
            sw.Start();&#xD;
&#xD;
            &lt;span &gt;for&lt;/span&gt; (&lt;span &gt;int&lt;/span&gt; i = 0; i &amp;lt; 100; i++)&#xD;
            {&#xD;
                &lt;span &gt;using&lt;/span&gt; (SqlConnection conn = &lt;span &gt;new&lt;/span&gt; SqlConnection(connectionString))&#xD;
                {&#xD;
                    conn.Open();&#xD;
                }&#xD;
            }&#xD;
&#xD;
            sw.Stop();&#xD;
            Console.WriteLine(&lt;span &gt;"Without Pooling, average connection elapsed {0} ms"&lt;/span&gt;, sw.ElapsedMilliseconds / 100);&#xD;
        }&#xD;
&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;SqlConnection 默认是打开连接池的，如果要强制关闭，我们需要在连接字符串中加入 Pooling=False&lt;/p&gt;&#xD;
&lt;p&gt;调用程序如下：&lt;/p&gt;&lt;pre &gt;Test.SqlConnectionTest.OpenWithoutPooling();&#xD;
                Console.WriteLine(&lt;span &gt;"Waiting for 10s"&lt;/span&gt;);&#xD;
                System.Threading.Thread.Sleep(10 * 1000);&#xD;
                Test.SqlConnectionTest.OpenWithoutPooling();&#xD;
                Console.WriteLine(&lt;span &gt;"Waiting for 600s"&lt;/span&gt;);&#xD;
                System.Threading.Thread.Sleep(600 * 1000);&#xD;
                Test.SqlConnectionTest.OpenWithoutPooling();&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;下面是测试结果&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Without Pooling, first connection elapsed 13 ms&lt;br /&gt;Without Pooling, average connection elapsed 5 ms&lt;br /&gt;Wating for 10s&lt;br /&gt;Without Pooling, first connection elapsed 6 ms&lt;br /&gt;Without Pooling, average connection elapsed 4 ms&lt;br /&gt;Wating for 600s&lt;br /&gt;Without Pooling, first connection elapsed 7 ms&lt;br /&gt;Without Pooling, average connection elapsed 4 ms&lt;/p&gt;&#xD;
&lt;p&gt;从这个测试结果看，关闭连接池后，平均每次连接大概要耗时4个毫秒左右，这个就是建立物理连接的平均耗时。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;下面再看默认情况下的测试代码&lt;/p&gt;&lt;pre &gt;&lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; OpenWithPooling()&#xD;
        {&#xD;
            &lt;span &gt;string&lt;/span&gt; connectionString =&#xD;
                &lt;span &gt;"Data Source=192.168.10.2; Initial Catalog=News; Integrated Security=True;"&lt;/span&gt;;&#xD;
            &#xD;
            Stopwatch sw = &lt;span &gt;new&lt;/span&gt; Stopwatch();&#xD;
&#xD;
            sw.Start();&#xD;
            &lt;span &gt;using&lt;/span&gt; (SqlConnection conn =&#xD;
                &lt;span &gt;new&lt;/span&gt; SqlConnection(connectionString))&#xD;
            {&#xD;
                conn.Open();&#xD;
            }&#xD;
&#xD;
            sw.Stop();&#xD;
            Console.WriteLine(&lt;span &gt;"With Pooling, first connection elapsed {0} ms"&lt;/span&gt;, sw.ElapsedMilliseconds);&#xD;
&#xD;
            sw.Reset();&#xD;
&#xD;
            sw.Start();&#xD;
&#xD;
            &lt;span &gt;for&lt;/span&gt; (&lt;span &gt;int&lt;/span&gt; i = 0; i &amp;lt; 100; i++)&#xD;
            {&#xD;
                &lt;span &gt;using&lt;/span&gt; (SqlConnection conn = &lt;span &gt;new&lt;/span&gt; SqlConnection(connectionString))&#xD;
                {&#xD;
                    conn.Open();&#xD;
                }&#xD;
            }&#xD;
&#xD;
            sw.Stop();&#xD;
            Console.WriteLine(&lt;span &gt;"With Pooling, average connection elapsed {0} ms"&lt;/span&gt;, sw.ElapsedMilliseconds / 100);&#xD;
        }&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;调用代码&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;pre &gt;Test.SqlConnectionTest.OpenWithPooling();&#xD;
                Console.WriteLine(&lt;span &gt;"Waiting for 10s"&lt;/span&gt;);&#xD;
                System.Threading.Thread.Sleep(10 * 1000);&#xD;
                Test.SqlConnectionTest.OpenWithPooling();&#xD;
                Console.WriteLine(&lt;span &gt;"Waiting for 600s"&lt;/span&gt;);&#xD;
                System.Threading.Thread.Sleep(600 * 1000);&#xD;
                Test.SqlConnectionTest.OpenWithPooling();&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
测试结果&lt;/p&gt;&#xD;
&lt;p&gt;With Pooling, first connection elapsed 119 ms&lt;br /&gt;With Pooling, average connection elapsed 0 ms&lt;br /&gt;Waiting for 10s&lt;br /&gt;With Pooling, first connection elapsed 0 ms&lt;br /&gt;With Pooling, average connection elapsed 0 ms&lt;br /&gt;Waiting for 600s&lt;br /&gt;With Pooling, first connection elapsed 6 ms&lt;br /&gt;With Pooling, average connection elapsed 0 ms&lt;br /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这个测试结果看，第一次耗时是119ms，这是因为我在测试代码中，首先运行的是这个测试过程，119 ms 是程序第一次启动时的首次连接耗时，这个耗时可能不光包括连接数据库的时间，还有 ado.net 自己初始化的用时，所以这个用时可以不管。10秒以后在执行这个测试过程，首次执行的时间变成了0ms，这说明连接池机制发生了作用，SqlConnection Close 后，物理连接并没有被关闭，所以10秒后再执行，连接几乎没有用时间。&lt;/p&gt;&#xD;
&lt;p&gt;但我们发现一个有趣的现象，10分钟后，首次连接时间变成了6ms，这个和前面不打开连接池的测试用时几乎一样，也就是说10分钟后，物理连接被关闭了，又重新打开了一个物理连接。这个现象是因为连接池有个超时时间，默认情况下应该在5-10分钟之间，如果在此期间没有任何的连接操作，物理连接就会被关闭。那么我们有没有办法始终保持物理连接呢？方法是有的。&lt;/p&gt;&#xD;
&lt;p&gt;连接池设置中有一个最小连接池大小，默认为0，我们把它设置为大于0的值就可以保持若干物理连接始终不释放了。看代码&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;pre &gt;&lt;span &gt;public&lt;/span&gt; &lt;span &gt;static&lt;/span&gt; &lt;span &gt;void&lt;/span&gt; OpenWithPooling(&lt;span &gt;int&lt;/span&gt; minPoolSize)&#xD;
        {&#xD;
            &lt;span &gt;string&lt;/span&gt; connectionString =&#xD;
                &lt;span &gt;string&lt;/span&gt;.Format(&lt;span &gt;"Data Source=192.168.10.2; Initial Catalog=News; Integrated Security=True;Min Pool Size={0}"&lt;/span&gt;,&#xD;
                    minPoolSize);&#xD;
&#xD;
            Stopwatch sw = &lt;span &gt;new&lt;/span&gt; Stopwatch();&#xD;
&#xD;
            sw.Start();&#xD;
            &lt;span &gt;using&lt;/span&gt; (SqlConnection conn =&#xD;
                &lt;span &gt;new&lt;/span&gt; SqlConnection(connectionString))&#xD;
            {&#xD;
                conn.Open();&#xD;
            }&#xD;
&#xD;
            sw.Stop();&#xD;
            Console.WriteLine(&lt;span &gt;"With Pooling Min Pool Size={0}, first connection elapsed {1} ms"&lt;/span&gt;, &#xD;
                minPoolSize, sw.ElapsedMilliseconds);&#xD;
&#xD;
            sw.Reset();&#xD;
&#xD;
            sw.Start();&#xD;
&#xD;
            &lt;span &gt;for&lt;/span&gt; (&lt;span &gt;int&lt;/span&gt; i = 0; i &amp;lt; 100; i++)&#xD;
            {&#xD;
                &lt;span &gt;using&lt;/span&gt; (SqlConnection conn = &lt;span &gt;new&lt;/span&gt; SqlConnection(connectionString))&#xD;
                {&#xD;
                    conn.Open();&#xD;
                }&#xD;
            }&#xD;
&#xD;
            sw.Stop();&#xD;
            Console.WriteLine(&lt;span &gt;"With Pooling Min Pool Size={0}, average connection elapsed {1} ms"&lt;/span&gt;, &#xD;
                minPoolSize, sw.ElapsedMilliseconds / 100);&#xD;
        }&#xD;
&#xD;
&lt;/pre&gt;&#xD;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&#xD;
{&#xD;
	font-size: small;&#xD;
	color: black;&#xD;
	font-family: consolas, "Courier New", courier, monospace;&#xD;
	background-color: #ffffff;&#xD;
	/*white-space: pre;*/&#xD;
}&#xD;
.csharpcode pre { margin: 0em; }&#xD;
.csharpcode .rem { color: #008000; }&#xD;
.csharpcode .kwrd { color: #0000ff; }&#xD;
.csharpcode .str { color: #006080; }&#xD;
.csharpcode .op { color: #0000c0; }&#xD;
.csharpcode .preproc { color: #cc6633; }&#xD;
.csharpcode .asp { background-color: #ffff00; }&#xD;
.csharpcode .html { color: #800000; }&#xD;
.csharpcode .attr { color: #ff0000; }&#xD;
.csharpcode .alt &#xD;
{&#xD;
	background-color: #f4f4f4;&#xD;
	width: 100%;&#xD;
	margin: 0em;&#xD;
}&#xD;
.csharpcode .lnum { color: #606060; }&#xD;
&lt;/style&gt;&#xD;
&#xD;
&lt;p&gt;其实只要在连接字符串中加入一个 Min Pool Size=n 就可以了。&lt;/p&gt;&#xD;
&lt;p&gt;调用代码&lt;/p&gt;&lt;pre &gt;Test.SqlConnectionTest.OpenWithPooling(1);&#xD;
                Console.WriteLine(&lt;span &gt;"Waiting for 10s"&lt;/span&gt;);&#xD;
                System.Threading.Thread.Sleep(10 * 1000);&#xD;
                Test.SqlConnectionTest.OpenWithPooling(1);&#xD;
                Console.WriteLine(&lt;span &gt;"Waiting for 600s"&lt;/span&gt;);&#xD;
                System.Threading.Thread.Sleep(600 * 1000);&#xD;
                Test.SqlConnectionTest.OpenWithPooling(1);&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;With Pooling Min Pool Size=1, first connection elapsed 5 ms&lt;br /&gt;With Pooling Min Pool Size=1, average connection elapsed 0 ms&lt;br /&gt;Waiting for 10s&lt;br /&gt;With Pooling Min Pool Size=1, first connection elapsed 0 ms&lt;br /&gt;With Pooling Min Pool Size=1, average connection elapsed 0 ms&lt;br /&gt;Waiting for 600s&lt;br /&gt;With Pooling Min Pool Size=1, first connection elapsed 0 ms&lt;br /&gt;With Pooling Min Pool Size=1, average connection elapsed 0 ms&lt;br /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我们可以看到当 Min Pool Size = 1&amp;nbsp; 时，除了首次连接用时5ms以外，即便过了10分钟，用时还是0ms，物理连接没有被关闭。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;多线程调用问题&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;多线程调用我也做了测试，这里不贴代码了，我大概讲一下结果。如果是多线程访问 SqlConnection ，注意是通过 new SqlConnection 方式访问，&lt;/p&gt;&#xD;
&lt;p&gt;那么这里有两个问题，如果后一个线程在前一个线程 Close 前调用了Open操作，那么 Ado.net 不可能复用一个物理连接，它将为第二个线程分配一个新的物理连接。如果后一个线程 Open&amp;nbsp; 时，前一个线程已经 Close 了，则新的线程使用前一个线程的物理连接。也就是说，如果同时有n个线程连接数据库，最多情况下会创建n条物理连接，最少情况下为1条。如果创建n条物理连接，则用时理论上等于 n * t / cpu , n 为线程数，t 为每次创建物理连接的用时，前面测试的结果大概是5-10ms左右，cpu 为当前机器的CPU数量。另外网络，服务器的负荷也影响这个用时。为了保证在大并发时，尽量少的创建新的物理连接，我们可以适当把 Min Pool Size 调大一些，但也不要太大，因为单个机器TCP链路的数量是有限的，详见我另外一篇文章 &lt;a href="http://www.cnblogs.com/eaglet/archive/2010/09/21/1832233.html"&gt;Windows 下单机最大TCP连接数&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;连接字符串中关于 连接池方面的参数&lt;/p&gt;&#xD;
&lt;p&gt;见下面链接 &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectionstring%28v=VS.80%29.aspx" target="_blank"&gt;SqlConnection.ConnectionString Property&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;IIS 回收应用程序池对连接池的影响&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在做 ASP.NET 程序时，我们会发现，如果网站20分钟不访问，再次访问就会比较慢，这是因为IIS默认的 idle timeout 是20分钟，如果在20分钟内没有一个访问，IIS 将回收应用程序池，回收应用程序池的结果就相当于应用程序被重启，所有原来的全局变量，session, 物理连接都将清空。回收应用程序池后首次访问，相当于前面我们看到的程序启动后第一次访问数据库，连接的建立时间将比较长。所以如果网站在某些时段访问量很少的话，需要考虑 idle timeout 是否设置合理。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/eaglet/aggbug/2230197.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/eaglet/archive/2011/10/31/2230197.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/eaglet/archive/2011/10/25/2223297.html</id><title type="text">Windows 2008 server + IIS 7 设置身份模拟(ASP.NET impersonation)</title><summary type="text">IIS7 与 IIS 6 相比有了很大的改动，原来在 IIS 6 下可以的设置到了 IIS 7 下有的会发生变化。身份模拟的配置上，IIS7 和 IIS6有很大不同，网上IIS6的身份模拟的文章比较多，但介绍IIS7的比较少，我把的一些折腾的经验在这篇博客中写下来，以供参考。</summary><published>2011-10-24T23:48:00Z</published><updated>2011-10-24T23:48:00Z</updated><author><name>eaglet</name><uri>http://www.cnblogs.com/eaglet/</uri></author><link rel="alternate" href="http://www.cnblogs.com/eaglet/archive/2011/10/25/2223297.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/eaglet/archive/2011/10/25/2223297.html"/><content type="html">&lt;p&gt;作者：eaglet&lt;/p&gt;&#xD;
&lt;p&gt;转载请注明出处&lt;/p&gt;&#xD;
&lt;p&gt;IIS7 与 IIS 6 相比有了很大的改动，原来在 IIS 6 下可以的设置到了 IIS 7 下有的会发生变化。身份模拟的配置上，IIS7 和 IIS6有很大不同，网上IIS6的身份模拟的文章比较多，但介绍IIS7的比较少，我把的一些折腾的经验在这篇博客中写下来，以供参考。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;IIS 7 有两种 ASP.NET Application Mode。&lt;/p&gt;&#xD;
&lt;p&gt;一种是 集成模式(Integrated Mode) 这个是默认的模式，也是微软推荐的模式，另一种是 经典模式(Classic Mode) ，这种模式是用于兼容老版本。集成模式使用更方便而且安全性更好，不需要把模拟帐户的用户名和密码写在配置文件中，这样更安全也更方便。既然我们已经用了IIS 7，那么我们还是按微软推荐的方式使用集成模式比较好。&lt;/p&gt;&#xD;
&lt;p&gt;集成模式下，身份模拟可以完全通过界面来完成：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/eaglet/201110/20111025072949358.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" alt="image" src="http://images.cnblogs.com/cnblogs_com/eaglet/201110/201110250729539392.png" border="0" height="455" width="586" /&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;首先如上图所示，IIS 7 在 Server Level 下有个 IIS-&amp;gt; Authentication ，双击这个图标我们看到下面这个图：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/eaglet/201110/201110250729569232.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" alt="image" src="http://images.cnblogs.com/cnblogs_com/eaglet/201110/201110250730008516.png" border="0" height="241" width="584" /&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在这个图中我们看到 IIS7 多了一个 ASP.NET Impersonation 的功能，在 Actions 里面点 Enable 开启身份模拟功能，然后点 Edit 编辑身份模拟。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/eaglet/201110/201110250730025333.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" alt="image" src="http://images.cnblogs.com/cnblogs_com/eaglet/201110/201110250730044518.png" border="0" height="178" width="353" /&gt;&lt;/a&gt;&amp;nbsp; &lt;/p&gt;&#xD;
&lt;p&gt;我们看到上面这个编辑框，在这个编辑框中，我们指定要进行身份模拟的帐号，这个帐号必须是本地已经存在的帐号，点 Set 输入这个帐号的名称和密码。&lt;/p&gt;&#xD;
&lt;p&gt;然后点OK。&lt;/p&gt;&#xD;
&lt;p&gt;到这里，按照 MSDN 中的帮助文档，身份模拟应该就算设置成功了。&lt;/p&gt;&#xD;
&lt;p&gt;然后我做了一个简单的测试页面看看身份模拟是否成功，测试程序如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;protected void Page_Load(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Response.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);&lt;br /&gt;} &#xD;
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;运行的结果居然是：&lt;/p&gt;&#xD;
&lt;p&gt;NT AUTHORITY\IUSR&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;也就是说 Asp.net 没有用我设置的这个 MyAccount 帐号模拟运行，而是仍然用IUSR 帐号模拟运行。查了好久，才发现是下面问题造成：&lt;/p&gt;&#xD;
&lt;p&gt;用 Virtual Studio 2008 生成网站时，web.config 文件中默认会有这样一个设置：&lt;/p&gt;&lt;pre&gt;&amp;lt;&lt;strong&gt;identity&lt;/strong&gt; &lt;strong&gt;impersonate&lt;/strong&gt;="true" /&amp;gt;&#xD;
&lt;/pre&gt;这个设置是为 IIS 6 做身份模拟而设置的。在这种情况下，用户身份的认证交给IIS来进行。当允许匿名登录时，IIS将一个匿名登录使用的标识（缺省情况下是IUSR）交给ASP.NET应用程序。当不允许匿名登录时，IIS将认证过的身份标识传递给ASP.NET应用程序。ASP.NET的具体访问权限由该账号的权限决定。 &#xD;
&lt;p&gt;这个设置在 IIS 7 下已经过时了，如果用古典模式，才需要这样设置。&lt;/p&gt;&#xD;
&lt;p&gt;找到问题原因后，我把 &amp;lt;&lt;strong&gt;identity&lt;/strong&gt; &lt;strong&gt;impersonate&lt;/strong&gt;="true" /&amp;gt;&amp;nbsp; 这个配置项从 web.config 中删除了。删除后，就可以用到前面在界面上配置的用户名来模拟帐号了。&lt;/p&gt;&#xD;
&lt;p&gt;然而先不要高兴的太早，紧接着就出现了新的问题。 错误如下：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Could not load file or assembly 'xxxx' or one of its dependencies. Access is denied.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;strong&gt;Description: &lt;/strong&gt;An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. &lt;br /&gt;&lt;strong&gt;Exception Details: &lt;/strong&gt;System.IO.FileLoadException: Could not load file or assembly 'GetPathFileLib' or one of its dependencies. Access is denied.&lt;br /&gt;&lt;strong&gt;Source Error:&lt;/strong&gt; &#xD;
&lt;p&gt;从错误提示看，应该是目前这个模拟帐户没有足够的权限去执行 bin 目录下的 xxxx.dll ，于是我把bin 目录赋予模拟帐户 MyAccount 完全控制的权限，结果还是不行，我在网上搜了一下，有人说需要将C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary 这个目录也设置为完全控制，于是照做了，还是不行。无奈之下，我把MyAccount 帐户加入了 IIS_IUSRS这个群组，问题终于解决。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/eaglet/201110/201110250730076243.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" alt="image" src="http://images.cnblogs.com/cnblogs_com/eaglet/201110/201110250730117686.png" border="0" height="563" width="465" /&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;现在我们再运行上面那个显示当前用户的代码显示结果为&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;div&gt;MachineName\MyAccout&lt;/div&gt;&lt;span style="color: red;"&gt;注意：&lt;/span&gt;我们必须要把 &amp;lt;&lt;strong&gt;identity&lt;/strong&gt; &lt;strong&gt;impersonate&lt;/strong&gt;="true" /&amp;gt; 删除才行，如果仅仅是设置为 &amp;lt;&lt;strong&gt;identity&lt;/strong&gt; &lt;strong&gt;impersonate&lt;/strong&gt;="false" /&amp;gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;模拟的帐户会变成&amp;nbsp; IIS APPPOOL\DefaultAppPool，这个设置是不正确的。&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;到这里IIS7 下设置身份模拟就全部完成了。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/eaglet/aggbug/2223297.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/eaglet/archive/2011/10/25/2223297.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/eaglet/archive/2011/10/24/2222227.html</id><title type="text">IIS 7.5 配置 FTP Passive 模式</title><summary type="text">本文简单介绍了windows server 2008 下IIS7.5 配置 FTP Passive 的方法</summary><published>2011-10-24T00:38:00Z</published><updated>2011-10-24T00:38:00Z</updated><author><name>eaglet</name><uri>http://www.cnblogs.com/eaglet/</uri></author><link rel="alternate" href="http://www.cnblogs.com/eaglet/archive/2011/10/24/2222227.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/eaglet/archive/2011/10/24/2222227.html"/><content type="html">&lt;p&gt;第一步:&lt;/p&gt; &lt;p&gt;进入 Server Level 的FTP Firewall Support &lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/eaglet/201110/201110240837325513.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/eaglet/201110/201110240837403274.png" width="752" height="581"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;第二步:&lt;/p&gt; &lt;p&gt;在 Data Channel Port Range 下配置 Passive mode 的端口号范围，注意这个范围的端口号必须要大于1023&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/eaglet/201110/201110240837452722.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/eaglet/201110/201110240837575372.png" width="757" height="585"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;第三步:&lt;/p&gt; &lt;p&gt;配置防火墙设置&lt;/p&gt; &lt;p&gt;如下图所示，我们需要将 Inbound Rules 的FTP Server Passive(FTP Passive Traffic-In) 这个规则开启，这个规则默认是开启的。&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/eaglet/201110/201110240838035128.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/eaglet/201110/20111024083810871.png" width="764" height="194"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;第四步：&lt;/p&gt; &lt;p&gt;重启服务器&lt;/p&gt; &lt;p&gt;配置好以上这些以后，必须要重启服务器防火墙才生效，我尝试过重启FTP 站点，重启IIS 或者重启那个 WWW&amp;nbsp; Publish 服务，都无法使防火墙生效。不知道为什么。如果有哪位朋友知道不重启服务就让防火墙生效的方法，麻烦在回复中告知一下，谢谢。&lt;/p&gt; &lt;img src="http://www.cnblogs.com/eaglet/aggbug/2222227.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/eaglet/archive/2011/10/24/2222227.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/eaglet/archive/2011/10/14/2211126.html</id><title type="text">web site publish 时几个问题的解决</title><summary type="text">一直做后台程序和winform ，很少做网站。我以前做的网站，都是直接把cs文件拷贝到服务器上执行，土得一塌糊涂。最近打算痛改前非，改成用发布功能发布，结果就出现了一些问题。 问题1： Compiler Error Message: CS0433: The type &amp;#39;ASP.global_asax&amp;#39; exists in both &amp;#39;c:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files\root\e22c2559\92c7e946\assembly\dl3\179fe88d\006</summary><published>2011-10-14T01:04:00Z</published><updated>2011-10-14T01:04:00Z</updated><author><name>eaglet</name><uri>http://www.cnblogs.com/eaglet/</uri></author><link rel="alternate" href="http://www.cnblogs.com/eaglet/archive/2011/10/14/2211126.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/eaglet/archive/2011/10/14/2211126.html"/><content type="html">&lt;p&gt;一直做后台程序和winform ，很少做网站。我以前做的网站，都是直接把cs文件拷贝到服务器上执行，土得一塌糊涂。最近打算痛改前非，改成用发布功能发布，结果就出现了一些问题。&lt;/p&gt; &lt;p&gt;问题1：&lt;/p&gt; &lt;p&gt;Compiler Error Message: CS0433: The type 'ASP.global_asax' exists in both 'c:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files\root\e22c2559\92c7e946\assembly\dl3\179fe88d\0064257c_f086cc01\App_global.asax.DLL' and 'c:\Windows\Microsoft.NET\Framework64\v2.0.50727\Temporary ASP.NET Files\root\e22c2559\92c7e946\App_global.asax.idkrgdjy.dll' &lt;p&gt;&lt;/p&gt; &lt;p&gt;这个错误，我折腾了好久，后来发现是发布后，bin 目录下已经有了一个 App_global.asax.dll ，而我的根目录下的 global.asax 没有删除，结果重复了。&lt;/p&gt; &lt;p&gt;删掉 global.asax ，问题解决了。但又出现另外一个问题，就是原来 global.asax 里面的代码不执行了。我用反编译工具检查了一下 App_global.asax.dll ，代码都已经编译了，但就是不执行，郁闷。&lt;/p&gt; &lt;p&gt;后来还是一个朋友提醒我要把 PrecompiledApp.config 这个文件拷贝到网站根目录下。拷贝上去后，问题解决。&lt;/p&gt; &lt;img src="http://www.cnblogs.com/eaglet/aggbug/2211126.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/eaglet/archive/2011/10/14/2211126.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/eaglet/archive/2011/08/10/2133184.html</id><title type="text">HubbleDotNet 开源全文搜索数据库项目--内存索引</title><summary type="text">经过2周多的努力，HubbleDotNet 的内存索引功能终于搞好了。有了内存索引，搜索不再去读硬盘，实时性大大提高了。hubble的内存索引不同于lucene 的内存索引，本文将具体介绍一下hubble 的内存索引功能和一些内部机制。</summary><published>2011-08-09T22:09:00Z</published><updated>2011-08-09T22:09:00Z</updated><author><name>eaglet</name><uri>http://www.cnblogs.com/eaglet/</uri></author><link rel="alternate" href="http://www.cnblogs.com/eaglet/archive/2011/08/10/2133184.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/eaglet/archive/2011/08/10/2133184.html"/><content type="html">&lt;p&gt;经过2周多的努力，HubbleDotNet 的内存索引功能终于搞好了。有了内存索引，搜索不再去读硬盘，实时性大大提高了。hubble的内存索引不同于lucene 的内存索引，本文将具体介绍一下hubble 的内存索引功能。&lt;/p&gt;&#xD;
&lt;p&gt;hubbledotnet 的内存索引被设计为一个可管理的可以持久化的内存索引，它和lucene 的内存索引有很大不同。lucene 的内存索引是不能持久化的，就是如果你用lucene 的内存索引，那么一旦机器重启，索引就没有了，要持久化，要同时做内存索引和文件索引。（lucene老版本是这样的，不知道新版本是否改进了)。另外 lucene 的内存索引是不可管理的，不能动态分配内存，所有索引全部加载到内存，如果索引很大，内存消耗非常大。hubbledotnet 的内存索引在设计上考虑到这些问题，下面具体谈谈。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;索引的持久化&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;hubbledotnet 的内存索引采用了读写分离的设计。写索引还是写入到文件中，读索引从内存中读取。这样即使机器重启，索引也不会丢失。而且由于读写分离，查询时完全不读取硬盘，查询的响应时间基本上非常确定，实时性比读取文件要提高很多。对于一些实时性要求比较高的搜索项目，由于数据修改非常频繁，并且要实时显示，在这种情况下，不可能每次增量或修改都优化索引，这样必然导致产生大量的索引碎片，如果不采用内存索引，每次搜索时就要读取大量的文件，搜索速度会受到很大影响，采用内存索引后，不管有多少文件，都是从内存读取，这个问题就得到彻底的解决。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;内存索引类型&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/eaglet/201108/201108100609002357.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/eaglet/201108/201108100609045482.png" width="672" height="388" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;如上图所示，要让表具备内存索引功能，只要在 tableinfo 中设置 RamIndexType 就可以了。&lt;/p&gt;&#xD;
&lt;p&gt;内存索引有如下4种类型：&lt;/p&gt;&#xD;
&lt;p&gt;NoCache : 这种类型表示不把索引加载到内存&lt;/p&gt;&#xD;
&lt;p&gt;Full: 这种类型表示把索引全部加载到内存&lt;/p&gt;&#xD;
&lt;p&gt;Dynamic: 这种类型表示动态加载内存，这个类型要和 RamIndex Min Load Size 参数配合使用，当一次读取超过最小加载大小时，将把相应的一块内存加载到内存中，这个最小加载大小的设置是为了控制加载内存的数量，较少的文件读取对搜索速度不会产生太大的影响，如果不论读取多少都加载到内存，会导致内存增长过快。最小加载大小默认值为80KB。hubbledotnet 的倒排索引压缩率比较高，每个文档在倒排索引中只占用2-4个字节，80KB大概相当于单个单词匹配2万到4万条记录左右。由于GC的大对象堆的门槛是85KB，所以我将这个默认值设置为80KB，以避免频繁到大对象堆中分配内存。&lt;/p&gt;&#xD;
&lt;p&gt;Small: 这种类型只对大小小于8MB的索引文件加载内存，这个类型主要用于那些索引更新比较频繁，且内存又不是很充裕的项目，因为这些项目往往会产生很多小的索引文件碎片。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;内存管理&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;内存索引有个很重要的问题就是随着索引文件的增大和搜索覆盖索引的增大，内存会逐渐增长，我们必须要有一个机制来控制这个内存的总数，不能把内存全部用光。hubbledotnet 专门做了这方面的设计。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/eaglet/201108/201108100609075185.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/eaglet/201108/201108100609117231.png" width="638" height="411" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;如上图所示，HubbleDotNet 提供了三个参数&lt;/p&gt;&#xD;
&lt;p&gt;RamIndexMemoryLimited: 这个参数指定内存索引的最大占用内存数，默认为64GB。一旦内存索引占用的内存数量超过这个设置或者hubbledotnet 发现申请内存时系统的物理内存可用数量少于100MB，这时HubbleDotNet 会对内存进行整理，将不经常访问的内存清除出去以腾出足够的内存。&lt;/p&gt;&#xD;
&lt;p&gt;RamIndexAllocedMemory: 这个参数是一个只读参数，它返回当前内存索引占用的内存数量。&lt;/p&gt;&#xD;
&lt;p&gt;LastSystemAvaliableMemory:这个参数是一个只读参数，它返回上一次分配内存时系统的可用物理内存数量。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;设置最大内存数&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;设置最大内存数的方法很简单，只要执行如下语句就可以，比如我们要设置内存索引最大占用内存数为2GB，我们只要执行:&lt;/p&gt;&#xD;
&lt;p&gt;sp_configure 'RamIndexMemoryLimited', 2048&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/eaglet/201108/201108100609143587.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/eaglet/201108/201108100609176047.png" width="524" height="226" /&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;font color="#ff0000"&gt;注意：这个参数的设置不需要重启Hubble服务，执行这个语句后，参数会立即生效。如果当前占用的内存数大于设置的内存数量，系统会自动整理内存，释放出多余的内存。&lt;/font&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;适用版本&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;1.1.5.4 版本及其以上版本&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;font size="5"&gt;返回 &lt;/font&gt;&lt;a href="http://www.cnblogs.com/eaglet/archive/2010/04/07/1706305.html"&gt;&lt;font size="5"&gt;HubbleDotNet 技术详解&lt;/font&gt;&lt;/a&gt; &lt;/p&gt;&lt;img src="http://www.cnblogs.com/eaglet/aggbug/2133184.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/eaglet/archive/2011/08/10/2133184.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/eaglet/archive/2011/07/24/2115483.html</id><title type="text">1.1.4.0 改动说明(这个版本单个关键字的查询速度大幅提高了)</title><summary type="text">1.1.4.0 版本对底层的查询算法做了很大改进，特别是对单个关键字的查询速度，原来版本当匹配100万时用时 130ms，这个版本用时只有30ms。这个速度大概是 lucene.net 的三倍左右。</summary><published>2011-07-24T09:11:00Z</published><updated>2011-07-24T09:11:00Z</updated><author><name>eaglet</name><uri>http://www.cnblogs.com/eaglet/</uri></author><link rel="alternate" href="http://www.cnblogs.com/eaglet/archive/2011/07/24/2115483.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/eaglet/archive/2011/07/24/2115483.html"/><content type="html">&lt;p&gt;1.1.4.0 版本对底层的查询算法做了很大改进，特别是对单个关键字的查询速度，原来版本当匹配100万时用时 130ms，这个版本用时只有30ms。&lt;br /&gt;原来版本的测试报告见 &lt;a href="http://www.cnblogs.com/eaglet/archive/2010/09/03/1816856.html"&gt;http://www.cnblogs.com/eaglet/archive/2010/09/03/1816856.html&lt;/a&gt; 这个速度大概是 lucene.net 的三倍左右。&lt;br /&gt;查询的性能应该还有进一步提高空间，等完全优化好，我出一个最新的测试报告。&lt;br /&gt;这个版本加载的速度有了显著提高，加载1000万行记录的索引，原来版本用时 23秒，这个版本用时只有1.9秒。&lt;br /&gt;由于底层算法改进，多关键字的查询速度也相应有了提高。&lt;br /&gt;这个版本对异步通信的连接池算法进行了优化，异步通信方式更加稳定和快速。&lt;br /&gt;这个版本我测出了 hubbledotnet 的单个关键字查询理论最快速度(多关键字的查询速度比单关键字快，这个是hubble 的算法特点)，这个速度建立在内存索引和部分代码用C++完成的基础上(目前还没有实现，只是理论值)，理论上在 2GHZ CPU 单核运行，匹配100万记录时,hubble的理论最快速度是 8ms. 这个速度已经非常快了，查询结果平均匹配100万行的话，总记录数一般应该在1亿以上了，这么大的数据量，单核8ms完成的话，4核的普通服务器一秒钟可以做500次查询，单机可以支持1亿以上行记录索引每天超过4000万次查询，如果再加上缓存，每天可以达到1亿次以上查询。 &lt;/p&gt;&lt;img src="http://www.cnblogs.com/eaglet/aggbug/2115483.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/eaglet/archive/2011/07/24/2115483.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/eaglet/archive/2011/07/07/2099965.html</id><title type="text">性能测试的一些备忘</title><summary type="text">性能测试的一些备忘</summary><published>2011-07-07T04:57:00Z</published><updated>2011-07-07T04:57:00Z</updated><author><name>eaglet</name><uri>http://www.cnblogs.com/eaglet/</uri></author><link rel="alternate" href="http://www.cnblogs.com/eaglet/archive/2011/07/07/2099965.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/eaglet/archive/2011/07/07/2099965.html"/><content type="html">&lt;p&gt;1. C# 和 C++ 执行指令的速度&lt;/p&gt;&lt;p&gt;测下来 C# 要慢1倍，这个和微软官方公布的是一致的。&lt;/p&gt;&lt;p&gt;对400 万 VInt&amp;nbsp; 读取，C# 用时最快为76ms， C++ 为 34ms&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;2. 虚拟方法比普通方法速度慢8倍&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;3. DLLImport win32 动态库，调用win32 函数的速度比直接调用 C# 自身函数速度慢100倍&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;4. InterLock 比 lock 速度快1倍&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;5. 用&amp;nbsp; Marshal.AllocHGlobal 连续申请和释放4M-400M之间大小的内存1000万次，没有发现明显内存碎片产生的迹象。&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/eaglet/aggbug/2099965.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/eaglet/archive/2011/07/07/2099965.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/eaglet/archive/2011/06/30/2094957.html</id><title type="text">盘古分词 2.3.3.0 -- 改进了批量导入功能</title><summary type="text">V 2.3.3.0 版本改进了批量导入功能可以批量导入单词，词性和词频了。</summary><published>2011-06-30T11:28:00Z</published><updated>2011-06-30T11:28:00Z</updated><author><name>eaglet</name><uri>http://www.cnblogs.com/eaglet/</uri></author><link rel="alternate" href="http://www.cnblogs.com/eaglet/archive/2011/06/30/2094957.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/eaglet/archive/2011/06/30/2094957.html"/><content type="html">&lt;p&gt;V 2.3.3.0 版本改进了批量导入功能&lt;/p&gt;&#xD;
&lt;p&gt;可以批量导入单词，词性和词频了。&lt;br /&gt;输入文件的格式为：&lt;br /&gt;单词|0x00000010|119&lt;br /&gt;子弹|0x00000008|28&lt;br /&gt;文本|0x00000100|2052&lt;br /&gt;其中第一个参数为单词，第二个参数为词性，第三个参数为词频 &#xD;
&lt;p&gt;需要下载代码编译，代码位置： &#xD;
&lt;p&gt;&lt;a title="http://pangusegment.codeplex.com/SourceControl/list/changesets" href="http://pangusegment.codeplex.com/SourceControl/list/changesets"&gt;http://pangusegment.codeplex.com/SourceControl/list/changesets&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/eaglet/aggbug/2094957.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/eaglet/archive/2011/06/30/2094957.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
