<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>赵翔鹏的Blog &#187; 计算机技术</title>
	<atom:link href="http://www.zhaoxiangpeng.com/category/%e8%ae%a1%e7%ae%97%e6%9c%ba%e6%8a%80%e6%9c%af/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.zhaoxiangpeng.com</link>
	<description>Xiangpeng&#039;s Thinkpad</description>
	<lastBuildDate>Sat, 21 Jan 2012 17:45:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>32位和64位的麻烦</title>
		<link>http://www.zhaoxiangpeng.com/2010/05/32%e4%bd%8d%e5%92%8c64%e4%bd%8d%e7%9a%84%e9%ba%bb%e7%83%a6/</link>
		<comments>http://www.zhaoxiangpeng.com/2010/05/32%e4%bd%8d%e5%92%8c64%e4%bd%8d%e7%9a%84%e9%ba%bb%e7%83%a6/#comments</comments>
		<pubDate>Sun, 23 May 2010 07:33:57 +0000</pubDate>
		<dc:creator>Xiangpeng</dc:creator>
				<category><![CDATA[计算机技术]]></category>

		<guid isPermaLink="false">http://www.zhaoxiangpeng.com/2010/05/32%e4%bd%8d%e5%92%8c64%e4%bd%8d%e7%9a%84%e9%ba%bb%e7%83%a6/</guid>
		<description><![CDATA[如果没有8G内存，还是不要装64位的Windows。今天又被折腾了一下。 装了个淘宝旺旺，店主发了个链接，我打开之后拍下宝贝去付款，IE反复提示安装控件，但怎么都装不上。而且还看到提示某SmartCard驱动无法安装。重启了一下还是不行，连网上银行都出毛病了，以前明明是好的啊。 这时忽然发现任务栏上有两个IE图标。。。 原来淘宝旺旺里面的链接会默认打开64位的IE。难怪安全控件会不兼容。还好是用Windows7，有图标分组的功能。如果不是看到两个IE图标，我估计还得折腾半天。看了一下，旺旺倒是32位的。不知道做旺旺的人是咋整成这样的。 最后说一个常见的误解。如果有4G内存，虽然32位的系统会导致部分内存无法访问，也许只能用到3.0-3.5G的内存，但其实你换成64位的系统之后未必就提高了内存的使用效率。以前一个指针占32bit，换成64位后每个指针都大了一倍，所以每个程序都会占更多的内存，最终又还回去了。再考虑到种种潜在的兼容性问题，还是用32位安心啊。]]></description>
			<content:encoded><![CDATA[<p>如果没有8G内存，还是不要装64位的Windows。今天又被折腾了一下。</p>
<p>装了个淘宝旺旺，店主发了个链接，我打开之后拍下宝贝去付款，IE反复提示安装控件，但怎么都装不上。而且还看到提示某SmartCard驱动无法安装。重启了一下还是不行，连网上银行都出毛病了，以前明明是好的啊。</p>
<p> 这时忽然发现任务栏上有两个IE图标。。。<a href="http://zhaoxiangpeng.com/blog/wp-content/uploads/2010/05/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://zhaoxiangpeng.com/blog/wp-content/uploads/2010/05/image_thumb.png" width="244" height="34" /></a>
<p>原来淘宝旺旺里面的链接会默认打开64位的IE。难怪安全控件会不兼容。还好是用Windows7，有图标分组的功能。如果不是看到两个IE图标，我估计还得折腾半天。看了一下，旺旺倒是32位的。不知道做旺旺的人是咋整成这样的。</p>
<p><a href="http://zhaoxiangpeng.com/blog/wp-content/uploads/2010/05/image1.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://zhaoxiangpeng.com/blog/wp-content/uploads/2010/05/image_thumb1.png" width="244" height="80" /></a> </p>
<p>最后说一个常见的误解。如果有4G内存，虽然32位的系统会导致部分内存无法访问，也许只能用到3.0-3.5G的内存，但其实你换成64位的系统之后未必就提高了内存的使用效率。以前一个指针占32bit，换成64位后每个指针都大了一倍，所以每个程序都会占更多的内存，最终又还回去了。再考虑到种种潜在的兼容性问题，还是用32位安心啊。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhaoxiangpeng.com/2010/05/32%e4%bd%8d%e5%92%8c64%e4%bd%8d%e7%9a%84%e9%ba%bb%e7%83%a6/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>时光</title>
		<link>http://www.zhaoxiangpeng.com/2010/03/%e6%97%b6%e5%85%89/</link>
		<comments>http://www.zhaoxiangpeng.com/2010/03/%e6%97%b6%e5%85%89/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 15:21:57 +0000</pubDate>
		<dc:creator>Xiangpeng</dc:creator>
				<category><![CDATA[心情]]></category>
		<category><![CDATA[计算机技术]]></category>

		<guid isPermaLink="false">http://www.zhaoxiangpeng.com/?p=656805</guid>
		<description><![CDATA[今天读到一篇好文章，互联网迟到的80后 (http://tech.sina.com.cn/i/2010-03-10/13573925303.shtml) 想了很多。 有商业模式的技术才是好技术。 最近无用的idea很多……列几个在这里吧： sql语言里能不能加入Debug.Assert这样的东西？写stored procedure的时候，或者是用sql来做一些数据挖掘工作的时候，一旦有一堆join，或是用了临时表，就很难验证最终数据的正确性。敲错一个地方，数据有个小偏差，很可能看不出来。 这本质上是个data constraint。也许可以用check constraint来实现，比如： ALTER TABLE dbo.Vendors ADD CONSTRAINT CK_Vendor_CreditRating     CHECK (CreditRating &#62;= 1 AND CreditRating &#60;= 5) 但是表达更复杂的约束的话，只能写个自定义函数，太麻烦了，管理起来也不容易。 总之，SQL是个不容易扩展的语言……也没有一个很好用的编辑环境。 怎么实现一个山寨版MapReduce。现有的开源实现都太复杂了，如果我就是想做一个最简单的多机并行计算系统呢？ 比如，能不能用Windows自带的DFS做分布式文件系统，用powershell 2.0来控制多台机器间的通讯。 能不能压缩一个进程占用的内存。至少把所有的VirtualAlloc重定向到一块特殊的内存空间。在系统内存不足时启用这个策略。 能不能给一个进程的private working set做一个单独的pagefile，从而降低pagefile.sys里的碎片。 最后这个也许更靠谱：好茶叶跟红酒一样怕氧化。能不能做个真空抽气袋来保存，每次喝点之后，抽光空气存起来。 Google了一下……果然已经有“真空抽气保鲜盒”这样的东西了……]]></description>
			<content:encoded><![CDATA[<p>今天读到一篇好文章，<a href="http://tech.sina.com.cn/i/2010-03-10/13573925303.shtml">互联网迟到的80后 (http://tech.sina.com.cn/i/2010-03-10/13573925303.shtml</a>)</p>
<p>想了很多。</p>
<p>有商业模式的技术才是好技术。</p>
<p>最近无用的idea很多……列几个在这里吧：</p>
<ul>
<li>sql语言里能不能加入Debug.Assert这样的东西？写stored procedure的时候，或者是用sql来做一些数据挖掘工作的时候，一旦有一堆join，或是用了临时表，就很难验证最终数据的正确性。敲错一个地方，数据有个小偏差，很可能看不出来。
<p>这本质上是个data constraint。也许可以用check constraint来实现，比如：</p>
<p>ALTER TABLE dbo.Vendors ADD CONSTRAINT CK_Vendor_CreditRating<br />
    CHECK (CreditRating &gt;= 1 AND CreditRating &lt;= 5)</p>
<p>但是表达更复杂的约束的话，只能写个自定义函数，太麻烦了，管理起来也不容易。</p>
<p>总之，SQL是个不容易扩展的语言……也没有一个很好用的编辑环境。</li>
<li>怎么实现一个山寨版MapReduce。现有的开源实现都太复杂了，如果我就是想做一个最简单的多机并行计算系统呢？<br />
比如，能不能用Windows自带的DFS做分布式文件系统，用powershell 2.0来控制多台机器间的通讯。</li>
<li>能不能压缩一个进程占用的内存。至少把所有的VirtualAlloc重定向到一块特殊的内存空间。在系统内存不足时启用这个策略。</li>
<li>能不能给一个进程的private working set做一个单独的pagefile，从而降低pagefile.sys里的碎片。</li>
<li>最后这个也许更靠谱：好茶叶跟红酒一样怕氧化。能不能做个真空抽气袋来保存，每次喝点之后，抽光空气存起来。<br />
Google了一下……果然已经有“真空抽气保鲜盒”这样的东西了……</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.zhaoxiangpeng.com/2010/03/%e6%97%b6%e5%85%89/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>由无数细节组成的系统</title>
		<link>http://www.zhaoxiangpeng.com/2009/08/%e7%94%b1%e6%97%a0%e6%95%b0%e7%bb%86%e8%8a%82%e7%bb%84%e6%88%90%e7%9a%84%e7%b3%bb%e7%bb%9f/</link>
		<comments>http://www.zhaoxiangpeng.com/2009/08/%e7%94%b1%e6%97%a0%e6%95%b0%e7%bb%86%e8%8a%82%e7%bb%84%e6%88%90%e7%9a%84%e7%b3%bb%e7%bb%9f/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 00:05:45 +0000</pubDate>
		<dc:creator>Xiangpeng</dc:creator>
				<category><![CDATA[形式化方法]]></category>
		<category><![CDATA[计算机技术]]></category>
		<category><![CDATA[软件工程]]></category>

		<guid isPermaLink="false">http://www.zhaoxiangpeng.com/?p=652645</guid>
		<description><![CDATA[计算机科学总是讲abstraction。这是源自数学的思维。formal methods可以说把这个发挥到了极致。但实际系统并不是这样。不要说构建Windows这样的庞然大物，就只是要写一个实用的小软件，就会遇到无数的细节。performance，security，scalability，debugging……除了functionality之外，有无数的事情要考虑。 传统的formal methods注重functionality也没错，因为在某些情形下（比如算法领域）functionality的正确性已经够难了。但这却不是软件工程中的主要问题。 我们能做的，就是尽量挣扎着把细节包装起来。比如，工程师做出一个个框架，分出若干个层次。框架可以帮助我们，但框架并不能解决一切问题，因为好的程序员必须了解各种细节。最近读一个基于ATL/WTL的真正的product code，发现这一年来看的n本书都没白看。比如，不懂C++内存布局，不懂各种calling convention，compiler的差异，就不能理解COM的设计（btw，强烈推荐《COM本质论》的第一章）。 researcher也自有办法。因为很多细节是正交的。在TASE'09上听到Zhong Shao做的invited talk，分不同的aspect去验证汇编代码的不同性质，这个是正确的思路，而且我觉得可以做更多的东西出来。以前做business process的security验证，这个也可以归到这个思路，不过high level的东西比较虚，做起来虽然不难但并不容易很深入。而Shao对汇编和机器本身建模，比如对interrupt handling建模，这个就很有新意，且竞争者较少——很多数学系出身做formal methods的人，都不太懂系统底层。 是的，跟C++和汇编相比，写Java很容易。不过事情一旦很容易，于工业上看，就不值钱了；于学术上看，就没啥好研究的了。所以，重视各种细节吧。]]></description>
			<content:encoded><![CDATA[<p>计算机科学总是讲abstraction。这是源自数学的思维。formal methods可以说把这个发挥到了极致。但实际系统并不是这样。不要说构建Windows这样的庞然大物，就只是要写一个实用的小软件，就会遇到无数的细节。performance，security，scalability，debugging……除了functionality之外，有无数的事情要考虑。</p>
<p>传统的formal methods注重functionality也没错，因为在某些情形下（比如算法领域）functionality的正确性已经够难了。但这却不是软件工程中的主要问题。</p>
<p>我们能做的，就是尽量挣扎着把细节包装起来。比如，工程师做出一个个框架，分出若干个层次。框架可以帮助我们，但框架并不能解决一切问题，因为好的程序员必须了解各种细节。最近读一个基于ATL/WTL的真正的product code，发现这一年来看的n本书都没白看。比如，不懂C++内存布局，不懂各种calling convention，compiler的差异，就不能理解COM的设计（btw，强烈推荐《COM本质论》的第一章）。</p>
<p>researcher也自有办法。因为很多细节是正交的。在TASE'09上听到Zhong Shao做的invited talk，分不同的aspect去验证汇编代码的不同性质，这个是正确的思路，而且我觉得可以做更多的东西出来。以前做business process的security验证，这个也可以归到这个思路，不过high level的东西比较虚，做起来虽然不难但并不容易很深入。而Shao对汇编和机器本身建模，比如对interrupt handling建模，这个就很有新意，且竞争者较少——很多数学系出身做formal methods的人，都不太懂系统底层。</p>
<p>是的，跟C++和汇编相比，写Java很容易。不过事情一旦很容易，于工业上看，就不值钱了；于学术上看，就没啥好研究的了。所以，重视各种细节吧。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhaoxiangpeng.com/2009/08/%e7%94%b1%e6%97%a0%e6%95%b0%e7%bb%86%e8%8a%82%e7%bb%84%e6%88%90%e7%9a%84%e7%b3%bb%e7%bb%9f/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C#和CLR的15个细节</title>
		<link>http://www.zhaoxiangpeng.com/2009/02/c%e5%92%8cclr%e7%9a%8415%e4%b8%aa%e7%bb%86%e8%8a%82/</link>
		<comments>http://www.zhaoxiangpeng.com/2009/02/c%e5%92%8cclr%e7%9a%8415%e4%b8%aa%e7%bb%86%e8%8a%82/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 23:36:37 +0000</pubDate>
		<dc:creator>Xiangpeng</dc:creator>
				<category><![CDATA[Windows编程]]></category>
		<category><![CDATA[计算机技术]]></category>

		<guid isPermaLink="false">http://www.zhaoxiangpeng.com/articles/c%e5%92%8cclr%e7%9a%8415%e4%b8%aa%e7%bb%86%e8%8a%82.html</guid>
		<description><![CDATA[这两周一直在training，一共听了4个课程，相当的累啊。 今天先把Jeffrey Richter的培训课：C# and CLR中讲到的一些东西整理一下： foreach的性能问题 foreach(string s in rows) { foo(s); }的实现是： IEnumerator e = rows.GetEnumerator(); try { string s; while (e.MoveNext()) { s = (String) e.Current; foo(s); } } finally { IDisposable d = e as IDisposable; if (d != null) d.Dispose(); } 每一步都调用了e.MoveNext()和e.Current两个方法；而大多数时候，完全有可能优化为一次调用。显然这对性能是有影响的。虽然foreach对于数组作了单独的优化（编译成for循环），但这还是值得注意的。 那么，怎么做比较快？ 对于List等Collection，可以用ForEach(Action&#60;T&#62; action)，FindAll(Predicate&#60;T&#62; match)，ConvertAll&#60;U&#62;(Converter&#60;T, U&#62; converter)等方法。它们比较快，但不是所有实现IEnumerable的类都提供。 LINQ追求compatiblity，而不是performance。因此LINQ的实现完全采用了foreach。值得注意。 yield的实现原理 实现一个支持IEnumerable的对象时，一般会用到yield关键字，这样foreach遍历这个对象时，可以做到lazy [...]]]></description>
			<content:encoded><![CDATA[<p>这两周一直在training，一共听了4个课程，相当的累啊。</p>
<p>今天先把Jeffrey Richter的培训课：C# and CLR中讲到的一些东西整理一下：</p>
<ol>
<li><strong>foreach的性能问题 </strong>      </p>
<p>foreach(string s in rows) { foo(s); }的实现是：       </li>
<div>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">IEnumerator e = rows.GetEnumerator();
<span style="color: #0000ff">try</span> {
  <span style="color: #0000ff">string</span> s;
  <span style="color: #0000ff">while</span> (e.MoveNext()) {
    s = (String) e.Current;
    foo(s);
  }
}
<span style="color: #0000ff">finally</span> {
  IDisposable d = e <span style="color: #0000ff">as</span> IDisposable;
  <span style="color: #0000ff">if</span> (d != <span style="color: #0000ff">null</span>) d.Dispose();
}</pre>
<p>每一步都调用了e.MoveNext()和e.Current<strong>两个</strong>方法；而大多数时候，完全有可能优化为一次调用。显然这对性能是有影响的。虽然foreach对于数组作了单独的优化（编译成for循环），但这还是值得注意的。</p>
<p>那么，怎么做比较快？</p>
<p>对于List等Collection，可以用ForEach(Action&lt;T&gt; action)，FindAll(Predicate&lt;T&gt; match)，ConvertAll&lt;U&gt;(Converter&lt;T, U&gt; converter)等方法。它们比较快，但不是所有实现IEnumerable的类都提供。</p>
<p>LINQ追求compatiblity，而不是performance。因此LINQ的实现完全采用了foreach。值得注意。</p>
</div>
</ol>
<ol>
<li><strong>yield的实现原理 </strong>
<p>实现一个支持IEnumerable的对象时，一般会用到yield关键字，这样foreach遍历这个对象时，可以做到lazy evaluation。例如：</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">class</span> MyCollection: IEnumerable&lt;<span style="color: #0000ff">char</span>&gt; {
  <span style="color: #0000ff">private</span> <span style="color: #0000ff">string</span> s; ...
  <span style="color: #0000ff">public</span> IEnumerable&lt;<span style="color: #0000ff">char</span>&gt; GetEnumerator() {
    <span style="color: #0000ff">for</span> (<span style="color: #0000ff">int</span> i=0; i&lt;s.Length; i++) {
      <span style="color: #0000ff">yield</span> <span style="color: #0000ff">return</span> s[i];
    }
  }
}</pre>
</p></div>
<p>执行到yield时函数返回，下次调用时，接着上次运行的位置继续运行。这个continuation的效果是怎么做的呢？</p>
<p>包含yield的函数都会被编译器做成一个<strong>状态机</strong>。每调一次，就接着上次的状态继续运行。简单有效啊。我一直以为要有什么特殊的办法呢。</p>
<p></li>
<li><strong>exception handling的实现决定了throw的performance较差。 </strong>
<p>可以用Int32.TryParse代替try{Int32.Parse…}catch{…}，稍快一点。类似地建议使用Dictionary.TryGetValue。</p>
<p></li>
<li><strong>.Net CLR执行引擎对应于MSCorWks.dll和MSCorEE.dll这两个文件。<br />
      <br /></strong></li>
<li><strong>.Net 3.0, 3.5没有对CLR作任何修改。</strong>
<p>所有增加的东西（比如LINQ）都是syntactic sugar，只改了C#编译器而已。</p>
<p></li>
<li><strong>AppDomain<br />
      <br /></strong></p>
<p>如果把.Net虚拟机看成一个虚拟操作系统，AppDomain的概念则类似于操作系统中的进程。</p>
<p>可以用代码创建一个AppDomain，然后动态加载/卸载assembly，还可以设置权限，相当于提供了一个沙箱。</p>
<p>跨AppDomain的调用类似于RPC。</p>
<p>调用某个AppDomain内部的obj.foo(x)时，.net会自动帮你做出一个proxy object，你所调用的obj其实是一个proxy object。传给foo的参数x会先被被marshal，以保证AppDomain被安全隔离。</p>
<p>谁用AppDomain？SQL Server用这个技术实现managed存储过程。IIS会把不同的Web Application放在不同的AppDomain里，以实现动态装卸。</p>
<p></li>
<li><strong>动态载入Assembly的陷阱</strong>
<p>Sytem.Reflection.Assembly.LoadFrom(pathName)并不会载入pathName所指定的dll，而是看看pathName那个dll的名字、版本，然后到系统默认位置去找。（陷阱啊）</p>
<p></li>
<li><strong>C#里用reflection创建一个新对象
<p></strong>用Activator.CreateInstance。（奇怪的名字啊。）</p>
<p></li>
<li><strong>C#泛型之“where”</strong>
<p>可以用“where”来限定T的接口。例如</p>
<p>static T min&lt;T&gt;(T arg1, T arg2) where T: IComparable&lt;T&gt; {…}</p>
<p>不写where的话，就不能调arg1.CompareTo(arg2)。</p>
<p>为啥不把T换成IComparable？一是为保证arg1, arg2一定是同一个类型，二是泛型的效率更高。（JIT会为不同类型的T各生成一份native code，从而避免了boxing）</p>
<p>更多where的细节：</p>
<p>* 要想调T t1 = new T()，必须声明where T: new()或者where T: struct</p>
<p>* 要写T t2 = null，必须声明where T: class</p>
<p>* T z = default(T)是一个特殊的用法，会把T的每个bit都置为0。</p>
<p>* 假设定义了Foo&lt;T&gt;(T x, T y)，则if (x==null) … 是可以通过的，虽然C#中value type的值不允许为null（例如int a=null是错的）。这是因为，此时的语义是一致的，反正if里面的操作不被执行就是了，所以编译器对这种特殊情况网开一面。</p>
<p>* if (x==y)不行，除非写了where T: baseclass。（这里我也没理解为啥。。。&gt;_&lt;好像说是不知道应该用reference比较还是value比较？）</p>
<p></li>
<li><strong>匿名函数的背后。。。</strong>
<p>在C# 2.0以后可以用匿名的delegate，如ThreadPool.QueueWorkItem(delegate (Object obj) { Console.WriteLine(obj); })</p>
<p>但编译器的实现会带来一点点overhead，会生成一个小小的静态WaitCallback对象，可以用Reflector看生成的代码。（不要打开Reflector的optimization，否则就看不到了）</p>
<p>如果是自己写的话，可以选择每次动态建立一个WaitCallback对象然后销毁。当然这样做性能可能差一些，但这里的idea是：编译器会自动做一些事，但不一定是你所希望的。在使用这些高级feature前，最好先搞清楚背后发生了什么。</p>
<p>另一个细节：如果匿名函数中使用了外层函数的局部变量（即所谓的function closure），会导致创建额外的shared-state object，把用到的局部变量做成一个新对象传给匿名函数。</p>
<p>上述描述同样适用于lambda函数。因为C#的lambda函数就是匿名函数，改了改语法而已。</p>
<p></li>
<li><strong>Nullable type<br />
      <br /></strong></p>
<p>虽然C#要求value type的值不能是null，但写数据库程序时经常遇到某个值是null的情况。为此，C#2.0引入了Nullable type。例如，int? x = null。</p>
<p>int? x其实就是一个缩写，等价于Nullable&lt;int&gt; x。Nullable是预定义的一个类，简单地对x作了封装。（因为增加了一个类，显然对性能稍微有点影响）</p>
<p>这个小改动的实现其实很麻烦，需要修改CLR。为什么？因为原先的x是一个value type，现在则变成了一个object，看这个：</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">void</span> M(Object o) {
  <span style="color: #0000ff">if</span> (o=<span style="color: #0000ff">null</span>) {Bar();}
}
<span style="color: #0000ff">void</span> F() {
  <span style="color: #0000ff">int</span>? x = <span style="color: #0000ff">null</span>;
  M(x);
}</pre>
</p></div>
<p>如果CLR不专门做修正的话，上面的Bar()不会被执行。（思考题：想一想为什么~）</p>
<p>另外，C#还引入了一个默认值运算符“??”，称为null-coalescing operator。</p>
<p>一句话，x ?? value是 (x==null) ? value: x的简写。</p>
<p></li>
<li><strong>属性(property)的简单声明 </strong>
<p>public int x {get; private set;}是个很好用的句式。</p>
<p>注意，public int x {get;}是错误的，不能通过编译。</p>
<p></li>
<li><strong>Extension method<br />
      <br /></strong></p>
<p></p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #0000ff">static</span> <span style="color: #0000ff">class</span> MyExtMethods {
  <span style="color: #0000ff">static</span> <span style="color: #0000ff">public</span> GetFirstLetter(<span style="color: #0000ff">this</span> <span style="color: #0000ff">string</span> s) {<span style="color: #0000ff">return</span> s[0];}
}</pre>
</p></div>
<p>然后就可以用string s = “hello”; char ch = s.GetFirstLetter()了。</p>
<p>原理很简单，编译器把上面那句话翻译成MyExtMethods.GetFirstLetter(s)。LINQ就用到了这个技术。</p>
<p></li>
<li><strong>匿名类型的背后。。。 </strong>
<p>var o = new {name = “Xiangpeng”, id = 123 };</p>
<p>在这背后是编译器生成的一个匿名类，包含了两个<strong>只读</strong>属性，形如public int id { get {return _id;} }为什么不做成可读写的呢？</p>
<p>很微妙。匿名类自动生成了GetHashCode()，返回的是对所有属性的hash code做XOR的结果。如果允许修改属性值，那么Hash code的值就会变化；而这个可能会出问题~保险起见，只读吧。</p>
<p></li>
<li><strong>每个thread占1M物理内存<br />
      <br /></strong></p>
<p>在Win32编程中thread的1M stack空间是Reserve的，直到真正用时才占用物理内存；而在.net中，这1M空间直接被commit。</p>
<p>还好，可以在新建thread时指定stack size。不过这也比较危险，设小了怕不够。实际上，最好尽量避免创建thread——太多的thread要么导致CPU竞争和context switch，要么都block着浪费内存。建议是：能用ThreadPool就用ThreadPool。 </li>
</ol>
<p>累死了，写了这么多……Jeffrey还有一个更牛的课：.net threading。里面的东西更多……要不要再总结一下呢。。。<img alt="Thinking" src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/72_72.gif" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhaoxiangpeng.com/2009/02/c%e5%92%8cclr%e7%9a%8415%e4%b8%aa%e7%bb%86%e8%8a%82/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>一台牛机器</title>
		<link>http://www.zhaoxiangpeng.com/2009/01/%e4%b8%80%e5%8f%b0%e7%89%9b%e6%9c%ba%e5%99%a8/</link>
		<comments>http://www.zhaoxiangpeng.com/2009/01/%e4%b8%80%e5%8f%b0%e7%89%9b%e6%9c%ba%e5%99%a8/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 18:14:36 +0000</pubDate>
		<dc:creator>Xiangpeng</dc:creator>
				<category><![CDATA[计算机技术]]></category>

		<guid isPermaLink="false">http://www.zhaoxiangpeng.com/articles/%e4%b8%80%e5%8f%b0%e7%89%9b%e6%9c%ba%e5%99%a8.html</guid>
		<description><![CDATA[xb一下最近在用的服务器，昵称“栅栏机”，如图。 32G内存挺好的。我的开发用机有5G内存，感觉刚刚够。 操作系统必须考虑大多数用户的配置，以便采用最佳的管理策略，所以Windows的内核要不断升级。可以出一道考试题：如果有32G内存，那应该对Windows这样的Desktop OS做哪些修改，才能方便用户？ 还要多少年，一般的PC才能装上32G内存呢~]]></description>
			<content:encoded><![CDATA[<p>xb一下最近在用的服务器，昵称“栅栏机”，如图。<img alt="Open-mouthed" src="http://messenger.msn.com/MMM2006-04-19_17.00/Resource/emoticons/teeth_smile.gif">
<p>32G内存挺好的。我的开发用机有5G内存，感觉刚刚够。
<p>操作系统必须考虑大多数用户的配置，以便采用最佳的管理策略，所以Windows的内核要不断升级。可以出一道考试题：如果有32G内存，那应该对Windows这样的Desktop OS做哪些修改，才能方便用户？
<p>还要多少年，一般的PC才能装上32G内存呢~
<p><a href="http://www.zhaoxiangpeng.com/wp-content/uploads/12/1224/2009/01/clip-image001.png"><img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="clip_image001" src="http://www.zhaoxiangpeng.com/wp-content/uploads/12/1224/2009/01/clip-image001-thumb.png" width="562" height="538"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhaoxiangpeng.com/2009/01/%e4%b8%80%e5%8f%b0%e7%89%9b%e6%9c%ba%e5%99%a8/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>SQL Server 2008 Reporting Service使用技巧</title>
		<link>http://www.zhaoxiangpeng.com/2008/12/sql-server-2008-reporting-service-tips/</link>
		<comments>http://www.zhaoxiangpeng.com/2008/12/sql-server-2008-reporting-service-tips/#comments</comments>
		<pubDate>Tue, 30 Dec 2008 15:19:44 +0000</pubDate>
		<dc:creator>Xiangpeng</dc:creator>
				<category><![CDATA[Windows编程]]></category>
		<category><![CDATA[计算机技术]]></category>
		<category><![CDATA[ssrs]]></category>

		<guid isPermaLink="false">http://www.zhaoxiangpeng.com/articles/sql-server-2008-reporting-service%e4%bd%bf%e7%94%a8%e6%8a%80%e5%b7%a7.html</guid>
		<description><![CDATA[SSRS用来做报表很方便，据说比Crystal Reports好用。简单的说，你的报表数据来自SQL语句，然后就可以在类似Excel的环境中画图了。 说是这么说，实际做起来还是会遇到很多小麻烦。下面是总结的一些技巧： 改变图表上字体大小（如X轴、Y轴上的数字）： 先把LabelsAutoFitDisabled属性设为True ，然后再设置字体大小 Data Label显示设置： 在Series的SmartLabels里面有一些有用的选项。AllowOutsidePlotArea设为True比较好。 自定义Legend标题： 要右键选Series的属性，不是Legend的属性 Pie chart显示百分比： 在Report properties - code中加入如下代码： Public Function GetLabel(ByVal currentValue As Integer, ByVal totalValue As Integer) As String If currentValue / totalValue &#60; 0 Then '表示百分比小于1的不显示出来 Return " " Else Return Format(currentValue / totalValue, "P1") End If End Function 然后设置data label表达式：=Code.GetLabel(Count(Fields!IssueID.Value), Count(Fields!IssueID.Value, "Issues")) Pie [...]]]></description>
			<content:encoded><![CDATA[<p>SSRS用来做报表很方便，据说比Crystal Reports好用。简单的说，你的报表数据来自SQL语句，然后就可以在类似Excel的环境中画图了。</p>
<p>说是这么说，实际做起来还是会遇到很多小麻烦。下面是总结的一些技巧：</p>
<ol>
<li>
<h3>改变图表上字体大小（如X轴、Y轴上的数字）：</h3>
<p>先把LabelsAutoFitDisabled属性设为True ，然后再设置字体大小</li>
<li>
<h3>Data Label显示设置：</h3>
<p>在Series的SmartLabels里面有一些有用的选项。AllowOutsidePlotArea设为True比较好。</li>
<li>
<h3>自定义Legend标题：</h3>
<p>要右键选Series的属性，不是Legend的属性</li>
<li>
<h3>Pie chart显示百分比：</h3>
<p>在Report properties - code中加入如下代码：</p>
<p>Public Function GetLabel(ByVal currentValue As Integer, ByVal totalValue As Integer) As String</p>
<p>If currentValue / totalValue &lt; 0 Then '表示百分比小于1的不显示出来</p>
<p>Return " "</p>
<p>Else</p>
<p>Return Format(currentValue / totalValue, "P1")</p>
<p>End If</p>
<p>End Function</p>
<p>然后设置data label表达式：=Code.GetLabel(Count(Fields!IssueID.Value), Count(Fields!IssueID.Value, "Issues"))</li>
<li>
<h3>Pie chart排序</h3>
<p>右键点一个Category，在Category Group Properties中设置Sort表达式即可</p>
<p><a href="http://www.zhaoxiangpeng.com/wp-content/uploads/12/1224/2008/12/clip-image001.png"><img src="http://www.zhaoxiangpeng.com/wp-content/uploads/12/1224/2008/12/clip-image001-thumb.png" style="border-width: 0px" alt="clip_image001" border="0" height="363" width="601" /></a></li>
<li>
<h3>在Pie chart饼图外侧显示DataLabel：</h3>
<p>设置Series的CustomAttributes，PieLabelStyle=Outside</p>
<p><a href="http://www.zhaoxiangpeng.com/wp-content/uploads/12/1224/2008/12/clip-image002.png"><img src="http://www.zhaoxiangpeng.com/wp-content/uploads/12/1224/2008/12/clip-image002-thumb.png" style="border-width: 0px" alt="clip_image002" border="0" height="692" width="680" /></a></p>
<p>注意：参考AdventureWorks示例，有一个很好的饼图。（google上搜到的都是过时的东西）</li>
<li>
<h3>Asp.net中使用ReportViewer控件：</h3>
<p>必须在IIS的Handler Mappings中新建一个Managed Handler才能正常显示。 可以google搜索Reserved.ReportViewerWebControl.axd。</p>
<p><a href="http://www.zhaoxiangpeng.com/wp-content/uploads/12/1224/2008/12/clip-image003.png"><img src="http://www.zhaoxiangpeng.com/wp-content/uploads/12/1224/2008/12/clip-image003-thumb.png" style="border-width: 0px" alt="clip_image003" border="0" height="551" width="580" /></a></p>
<p><a href="http://www.zhaoxiangpeng.com/wp-content/uploads/12/1224/2008/12/clip-image004.png"><img src="http://www.zhaoxiangpeng.com/wp-content/uploads/12/1224/2008/12/clip-image004-thumb.png" style="border-width: 0px" alt="clip_image004" border="0" height="667" width="815" /></a></p>
<p>另一个解决方法：据说配置下web.config文件也可以搞定：</p>
<p>&lt;httpHandlers&gt;</p>
<p>    &lt;add path="Reserved.ReportViewerWebControl.axd" verb="*"</p>
<p>         type="Microsoft.Reporting.WebForms.HttpHandler,</p>
<p>               Microsoft.ReportViewer.WebForms,</p>
<p>               Version=8.0.0.0, Culture=neutral,</p>
<p>               PublicKeyToken=?????????????"</p>
<p>         validate="false" /&gt;</p>
<p>&lt;/httpHandlers&gt;</p>
<p><a href="http://www.knowsky.com/340782.html">http://www.knowsky.com/340782.html</a></li>
<li>
<h3>ReportViewer控件：</h3>
<p>可以设置ZoomMode属性为PageWidth，这样可以自动放缩。</p>
<p>图表放大时会失真,因为不是矢量图。建议把原始报表拉大一些，在页面中留一个小点的空，默认ZoomMode=PageWidth，用户选择100%就可以放大。</p>
<p>所有的toolbar按钮都可以选择显示或关闭，设置ShowXXX属性即可。</li>
<li>
<h3>其他：</h3>
<p>对报表修改之后要及时Deploy，才能看到效果。可以在VS的configuration manager里面设置，debug时自动deploy，比较方便。这个默认是没有打开的，如下图所示，建议把Deploy的对勾打上。</p>
<p><a href="http://www.zhaoxiangpeng.com/wp-content/uploads/12/1224/2008/12/clip-image005.png"><img src="http://www.zhaoxiangpeng.com/wp-content/uploads/12/1224/2008/12/clip-image005-thumb.png" style="border-width: 0px" alt="clip_image005" border="0" height="297" width="812" /></a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.zhaoxiangpeng.com/2008/12/sql-server-2008-reporting-service-tips/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>LINQ学习笔记</title>
		<link>http://www.zhaoxiangpeng.com/2008/12/linq-study-notes/</link>
		<comments>http://www.zhaoxiangpeng.com/2008/12/linq-study-notes/#comments</comments>
		<pubDate>Sun, 21 Dec 2008 08:11:01 +0000</pubDate>
		<dc:creator>Xiangpeng</dc:creator>
				<category><![CDATA[Windows编程]]></category>
		<category><![CDATA[计算机技术]]></category>

		<guid isPermaLink="false">http://www.zhaoxiangpeng.com/articles/linq-study-notes.html</guid>
		<description><![CDATA[什么是LINQ LINQ是C# 3.0的新功能，可以用统一的的语法（类似sql、或者是函数式语言）访问各种数据，包括数据库、XML、对象。 Anders Hejlsberg说LINQ是"It's about turning query set operations and transforms into first-class concepts of the language" (http://channel9.msdn.com/showpost.aspx?postid=114680)。我的感受是：LINQ可以取代SQL，成为一种统一Database、XML世界的查询语言。 举个例子： var bycity = from p in db.Products join o in db.Orders on p.productID equals o.productID   where o.ShipToCity == "Beijing" select new {o.orderID, p.productName}; foreach (d in bycity) ... //或者GridView1.DataSource = bycity 这里的db.doctors可以是数据库DataSet，可以是个xml文件，也可以是个List&#60;T&#62;。 所有的新关键字，比如var, from, [...]]]></description>
			<content:encoded><![CDATA[<h3>什么是LINQ</h3>
<p>LINQ是C# 3.0的新功能，可以用统一的的语法（类似sql、或者是函数式语言）访问各种数据，包括数据库、XML、对象。</p>
<p>Anders Hejlsberg说LINQ是"It's about turning query set  operations and transforms into first-class concepts of the language" (<a href="http://channel9.msdn.com/showpost.aspx?postid=114680" class="docLink" target="_blank">http://channel9.msdn.com/showpost.aspx?postid=114680</a>)。我的感受是：LINQ可以取代SQL，成为一种统一Database、XML世界的查询语言。</p>
<p>举个例子：</p>
<pre name="code" class="c-sharp:nogutter">
var bycity = from p in db.Products
             join o in db.Orders
             on p.productID equals o.productID
             where o.ShipToCity == "Beijing"
             select new {o.orderID, p.productName};
foreach (d in bycity) ...
//或者GridView1.DataSource = bycity</pre>
<p>这里的db.doctors可以是数据库DataSet，可以是个xml文件，也可以是个List&lt;T&gt;。</p>
<p>所有的新关键字，比如var, from, group, select...都是syntactic sugar。编译器会自动把它翻译成基于Lambda表达式的代码，最后翻译成.net 2.0的程序。var的类型是type inference推断出来的，是强类型的，不等于object；select相当于函数式语言中的Map，当然也支持函数式语言中的Reduce（叫做Aggregate）；函数式语言用到的Lambda表达式其实很容易用函数指针delegate实现；最后生成的是一个匿名类型(anonymous type）。</p>
<p>推荐这本小书：<a href="http://www.baidu.com/s?wd=LINQ%3A+The+Future+of+Data+Access+in+C%23+3.0&amp;cl=3" target="_blank">LINQ: The Future of Data Access in C# 3.0</a>，只要两小时就看完了。了解一点原理后再用LINQ就方便多了。</p>
<h3>LINQ和ASP.net</h3>
<p>对ASP.net程序员而言，LINQ主要的应用是用它代替SQL访问数据库。除了不用拼字符串了，一个好处是，LINQ是强类型的，所以用起来更安全。我可以这样写：</p>
<pre name="code" class="c-sharp:nogutter">
var query = db.Orders.Where(o=&gt;o.Description.Contains(txtDescription.Text));
// Contains会被翻译成SQL的LIKE
DateTime sinceDate = DateTime.Parse(txtSinceDate.Text);
query = query.Where(o=&gt;o.ShipDate &gt; date);
// o.ShipDate也是DateTime类型的，所以可以直接比较</pre>
<p>Lambda表达式很好用的。<br />
比较麻烦的是，现在有两套数据库访问框架：一个是LINQ to SQL，一个是LINQ to Entity。在用LINQ前，又要花点时间考虑用哪个框架好。</p>
<p>二者对于各种基本CRUD操作有很好的支持。LINQ to SQL可以理解为SQL的替代品，基本上跟SQL能一一对应起来；而LINQ to Entity是2008年8月才推出的，是一个更强大的ORM框架，对多对多关系的支持更好。</p>
<p>举个例子：假设一个表linkProductOrder里只有两列，productID和orderID，用于表达product和order的联系。在LINQ to SQL中这个表会被映射到一个类linkProductOrder，还需要自己写join；而LINQ to Entity中就不会出现这个类，直接用product.Orders和order.Products就可以实现互相访问，完全消除了写join的必要。</p>
<p>我的体会是：LINQ to Entity目前还不够稳定，还是LINQ to SQL保险。用ORM框架的一个问题是，刚开始用时会有lose control的感觉，出了问题完全不知道怎么回事，不像SQL，模型很简单清晰，一个query下去肯定不会出毛病。</p>
<p>我用LINQ to Entity时遇到了几个问题，比如数据库改变后没法重新刷新对象模型，只能删掉对象模型文件重建；还有一次不知道为何新建的对象存不进数据库，这时调试起来非常麻烦。对于复杂的含有多个join的查询，我一般都会先用sql server测试一下，再写成代码；LINQ to Entity不用写join是省了一点事，但是这样反而要在脑子里维护两种模型翻过来译过去。相比之下LINQ to SQL就没出过什么问题。</p>
<p>希望等LINQ to Entity的下个版本出来之后，这种问题会少一些。</p>
<p>总结：不是做广告，C#真的很好很强大。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhaoxiangpeng.com/2008/12/linq-study-notes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用Java调用.net的Web service</title>
		<link>http://www.zhaoxiangpeng.com/2008/11/use-java-to-call-dotnet-web-service/</link>
		<comments>http://www.zhaoxiangpeng.com/2008/11/use-java-to-call-dotnet-web-service/#comments</comments>
		<pubDate>Thu, 20 Nov 2008 15:30:20 +0000</pubDate>
		<dc:creator>Xiangpeng</dc:creator>
				<category><![CDATA[BPEL和CDL]]></category>
		<category><![CDATA[计算机技术]]></category>

		<guid isPermaLink="false">http://www.zhaoxiangpeng.com/articles/use-java-to-call-dotnet-web-service.html</guid>
		<description><![CDATA[Web service可以提高interoperability，可以实现跨平台的应用……听起来不错。但真的做一下，还是有很多小陷阱。 下面是最近做的小例子，用Java Axis2作为客户端调用.net写的web服务。支持自定义的数据结构（这个不是那么简单……）。 准备： 1、下载axis2 ，注意，不要google “axis”，那个是旧版的，一定要google“axis2”，目前的最新版本是1.41。 2、Visual studio 2008，C#。 这个不用说什么了。  服务端： 在visual studio里写个hello world服务很简单，函数前加个[WebMethod]就可以。但是， 如果用到自定义的类，比如下面定义的person类作为GetUserInfoByPerson服务的参数： namespace WebService1 { public class Person { public string IdentityNumber { get { return m_IdentityNumber; } set { m_IdentityNumber = value; } } private string m_IdentityNumber; } } 这时要注意，直接按Ctrl+F5后生成的wsdl不包括Person的定义。 正确的做法是加一行 [SoapRpcMethod(Action = "http://tempurl.org/GetUserInfoByPerson", RequestNamespace = "http://tempurl.org", Use=SoapBindingUse.Literal)] 代码如下： [...]]]></description>
			<content:encoded><![CDATA[<p>Web service可以提高interoperability，可以实现跨平台的应用……听起来不错。但真的做一下，还是有很多小陷阱。</p>
<p>下面是最近做的小例子，用Java Axis2作为客户端调用.net写的web服务。支持<strong>自定义的数据结构</strong>（这个不是那么简单……）。</p>
<p><strong>准备：</strong></p>
<p>1、下载axis2 ，注意，不要google “axis”，那个是旧版的，一定要google“axis2”，目前的最新版本是1.41。</p>
<p>2、Visual studio 2008，C#。 这个不用说什么了。</p>
<p><strong> 服务端：</strong></p>
<p>在visual studio里写个hello world服务很简单，函数前加个[WebMethod]就可以。但是， 如果用到自定义的类，比如下面定义的person类作为GetUserInfoByPerson服务的参数：</p>
<pre name="code" class="c-sharp:nogutter">
namespace WebService1
{
    public class Person
    {
        public string IdentityNumber
        {
            get { return m_IdentityNumber; }
            set { m_IdentityNumber = value; }
        }
        private string m_IdentityNumber;
    }
}</pre>
<p>这时要注意，直接按Ctrl+F5后生成的wsdl不包括Person的定义。</p>
<p>正确的做法是加一行<br />
[SoapRpcMethod(Action = "http://tempurl.org/GetUserInfoByPerson", RequestNamespace = "http://tempurl.org", Use=SoapBindingUse.Literal)]</p>
<p>代码如下：</p>
<pre name="code" class="c-sharp:nogutter">
[WebService(Namespace = "http://tempurl.org/")]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
[SoapRpcMethod(Action = "http://tempurl.org/GetUserInfoByPerson", RequestNamespace = "http://tempurl.org", Use=SoapBindingUse.Literal)]
// 不加这一句，wsdl中就不生成Person类型
public Person GetUserInfoByPerson(Person q)
{
Person p = new Person();
p.IdentityNumber = q.IdentityNumber+"123";
}
}</pre>
<p>现在Ctrl+F5运行这个服务，假设地址是http://localhost:56765/Service1.asmx，那就可以在http://localhost:56765/Service1.asmx?WSDL里看到，Person的定义已经出现了。</p>
<p><strong>客户端：</strong></p>
<p>axis2有一个不错的<a href="http://ws.apache.org/axis2/1_4_1/quickstartguide.html">quickstart教程</a>。axis2目录下面samples\faulthandling这个例子值得参考，里面有详细的readme.txt和build.xml。</p>
<p>1、用axis2自带的wsdl2java工具生成代码框架：</p>
<p>%AXIS2_HOME%\bin\wsdl2java.bat -uri http://localhost:56765/Service1.asmx?WSDL -u -o &lt;target  dir&gt;</p>
<p>这样会在target dir下生成一个目录，里面有现成的Person.java等代码。</p>
<p>2、写调用代码</p>
<p>在Eclipse里建好项目，加入axis2\lib目录下所有的jar包，把刚才生成的目录也拷进去。</p>
<p>然后可以写代码了：</p>
<pre name="code" class="java:nogutter">
package example;
import org.tempurl.*;
public final class MyClient {
  public static void main(String[] args) {
  try {
    Service1Stub service1Stub = new Service1Stub("http://localhost:8080/Service1.asmx");
    service1Stub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE);
    Service1 service1 = service1Stub;
    GetUserInfoByPerson req = new GetUserInfoByPerson();
    Person personReq = new Person();
    personReq.setIdentityNumber("123");
    req.setQ(personReq);
    GetUserInfoByPersonResponse response = service1.GetUserInfoByPerson(req);
    PersonE personResponse = response.getGetUserInfoByPersonResult();
    System.out.println("ID = " + personResponse.getIdentityNumber());
  } catch (Exception e) {
  e.printStackTrace();
}
}
}</pre>
<p>注意这一句！service1Stub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, Boolean.FALSE);</p>
<p>不做这个设置，一开始我怎么都调用失败，Axis2报告说HTTP send recv出错（记不清楚错误信息了）。用<a href="http://www.google.com/search?q=tcpmon">tcpmon</a>查看调用服务时的tcp传输，发现.net的web server根本不接受axis2的soap包。（btw，tcpmon是个不错的工具啊。）</p>
<p>google了很久发现原因是，<a href="http://johnwang71.spaces.live.com/Blog/cns!98FCE6D97A525653!281.entry">axis2在做http传输时采用了“chunked”模式，而.net的web server不支持。</a></p>
<p><span id="ctl00_MainContentPlaceholder_ctl01_ctl00_lblEntry">“axis中使用的是HTTP/1.0协议，而.NET和axis2使用的是HTTP/1.1协议，后两者的区别在于.NET未使用ns1的命名空间前缀打包SOAP请求，且axis2使用了Content-Encoding: chunked头。  </span>所以必须在axis2中设置一下。”</p>
<p><strong>总结：</strong></p>
<p>web服务调用还是很麻烦的。除了上面列举的问题，还可能有soap协议版本1.1和1.2不兼容之类的细节问题。在调试这类问题时，tcpmon是必备工具。</p>
<p>刚才讨论了如何用java调.net服务。如果反过来，不知是否会简单一点。</p>
<p>最后，其实我一年前就写过axis2 1.3的代码……可是昨天，除了知道这件事可以用axis2做，所有的细节都忘光了。还是花半个小时记下来比较安全。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhaoxiangpeng.com/2008/11/use-java-to-call-dotnet-web-service/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>T43风扇清洗记</title>
		<link>http://www.zhaoxiangpeng.com/2008/10/t43-fan-cleaning/</link>
		<comments>http://www.zhaoxiangpeng.com/2008/10/t43-fan-cleaning/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 13:38:19 +0000</pubDate>
		<dc:creator>Xiangpeng</dc:creator>
				<category><![CDATA[心情]]></category>
		<category><![CDATA[计算机技术]]></category>
		<category><![CDATA[T43 thinkpad]]></category>

		<guid isPermaLink="false">http://www.zhaoxiangpeng.com/articles/t43-fan-cleaning.html</guid>
		<description><![CDATA[T43风扇的噪声实在太大了，说它是拖拉机毫不为过。买新风扇太贵，买到旧风扇就更郁闷。自己动手吧！万一坏了呢……就去村里买个新的台式机~~ 抱着必死的决心，开始实施计划。按照网上的攻略，要用分析纯的无水酒精清洗风扇。哪里有卖的？攻略没说。从北大东门出来，过了马路向南走到中关村十字路口附近，东边有个凹进去的小路，路北侧有个不起眼的小店卖实验试剂，那里就有卖无水酒精的，一瓶10块钱，500ml。 回家之后准备好螺丝刀，开拆。我先找了张白纸，把背面所有的螺丝钉位置画在纸上，把拆下来的每个螺丝钉直接插在纸上的相应位置，这样就不会记错位置了。这个idea还不错吧：） 拆完背面的螺丝就可以取下掌托和键盘，然后再按攻略拆掉键盘下面、靠近左下角的一颗螺丝，就可以把边框打开。最后把风扇上的螺丝拆掉，很容易就把风扇取下来了。 风扇上的灰很多。我拿了个小盆儿，倒了300ml酒精进去，然后把风扇扔进去泡了泡，摇了摇，就当洗萝卜那么洗。5分钟后觉得差不多了，电吹风吹干，把所有螺丝装回去，搞定~ 虽然有的攻略说要用超声波清洗机，有的说要加黄油，甚至还有的说要把风扇拆开了洗……但实践证明简单泡一泡的效果也很好。只花10块钱，风扇安静了，又能听到硬盘的声音了~：）]]></description>
			<content:encoded><![CDATA[<p>T43风扇的噪声实在太大了，说它是拖拉机毫不为过。买新风扇太贵，买到旧风扇就更郁闷。自己动手吧！万一坏了呢……就去村里买个新的台式机~~</p>
<p>抱着必死的决心，开始实施计划。按照<a href="http://www.google.com/search?q=T43风扇清洗">网上的攻略</a>，要用分析纯的无水酒精清洗风扇。哪里有卖的？攻略没说。从北大东门出来，过了马路向南走到中关村十字路口附近，东边有个凹进去的小路，路北侧有个不起眼的小店卖实验试剂，那里就有卖无水酒精的，一瓶10块钱，500ml。</p>
<p>回家之后准备好螺丝刀，开拆。我先找了张白纸，把背面所有的螺丝钉位置画在纸上，把拆下来的每个螺丝钉直接插在纸上的相应位置，这样就不会记错位置了。这个idea还不错吧：）</p>
<p>拆完背面的螺丝就可以取下掌托和键盘，然后再按攻略拆掉键盘下面、靠近左下角的一颗螺丝，就可以把边框打开。最后把风扇上的螺丝拆掉，很容易就把风扇取下来了。</p>
<p>风扇上的灰很多。我拿了个小盆儿，倒了300ml酒精进去，然后把风扇扔进去泡了泡，摇了摇，就当洗萝卜那么洗。5分钟后觉得差不多了，电吹风吹干，把所有螺丝装回去，搞定~</p>
<p>虽然有的攻略说要用超声波清洗机，有的说要加黄油，甚至还有的说要把风扇拆开了洗……但实践证明简单泡一泡的效果也很好。只花10块钱，风扇安静了，又能听到硬盘的声音了~：）</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhaoxiangpeng.com/2008/10/t43-fan-cleaning/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>貌似Netbeans 6比Eclipse强大很多啊</title>
		<link>http://www.zhaoxiangpeng.com/2007/12/%e8%b2%8c%e4%bc%bcnetbeans-6%e6%af%94eclipse%e5%bc%ba%e5%a4%a7%e5%be%88%e5%a4%9a%e5%95%8a/</link>
		<comments>http://www.zhaoxiangpeng.com/2007/12/%e8%b2%8c%e4%bc%bcnetbeans-6%e6%af%94eclipse%e5%bc%ba%e5%a4%a7%e5%be%88%e5%a4%9a%e5%95%8a/#comments</comments>
		<pubDate>Thu, 13 Dec 2007 00:10:00 +0000</pubDate>
		<dc:creator>Xiangpeng</dc:creator>
				<category><![CDATA[计算机技术]]></category>

		<guid isPermaLink="false">http://www.zhaoxiangpeng.com/articles/%e8%b2%8c%e4%bc%bcnetbeans-6%e6%af%94eclipse%e5%bc%ba%e5%a4%a7%e5%be%88%e5%a4%9a%e5%95%8a.html</guid>
		<description><![CDATA[今天看了一个介绍Netbeans的视频：http://www.javalobby.org/eps/netbeans55/ 非常吃惊，原来Netbeans已经这么牛了，可以说绝不比Visual Studio差。 首先因为它是Sun的IDE，所以支持几乎所有的最新Java技术，比如JAX-WS，Mobility，BPEL，Java Persistence(类似)，JSF，还有一个很漂亮的visual web design界面；而且用起来非常容易（这主要归功于Java EE 5），极大的减少了代码量，把J2EE的门槛大大降低了。 其次是各个高级功能之间的互联。Eclipse的缺点是作些基本开发还好，但要开发复杂程序的时候要配一堆东西，像MyEclipse之类的第三方插件质 量虽然好，但毕竟不是“原厂出品”，插件一多就有点头痛，不仅风格不同，而且互相不能通讯。相比之下，Netbeans和Visual Studio的好处是设计之初就考虑到了种种高级功能之间的互相关联，所以可以做到“从数据库管理窗口里拖一个table到Web设计页面上”这样的效 果。 Websphere的确提供了很多功能，但Websphere的使用离不开IBM自己的一堆服务端程序，感觉用Websphere做开发的人好像从来不会配合MySQL一起的。JBuilder现在也逐渐没落了，所以还是装个开源的Netbeans吧。]]></description>
			<content:encoded><![CDATA[<p>今天看了一个介绍Netbeans的视频：<a href="http://www.javalobby.org/eps/netbeans55/">http://www.javalobby.org/eps/netbeans55/</a><br />
非常吃惊，原来Netbeans已经这么牛了，可以说绝不比Visual Studio差。</p>
<p>首先因为它是Sun的IDE，所以支持几乎所有的最新Java技术，比如JAX-WS，Mobility，BPEL，Java<br />
Persistence(类似)，JSF，还有一个很漂亮的visual web design界面；而且用起来非常容易（这主要归功于Java EE<br />
5），极大的减少了代码量，把J2EE的门槛大大降低了。</p>
<p>其次是各个高级功能之间的互联。Eclipse的缺点是作些基本开发还好，但要开发复杂程序的时候要配一堆东西，像MyEclipse之类的第三方插件质<br />
量虽然好，但毕竟不是“原厂出品”，插件一多就有点头痛，不仅风格不同，而且互相不能通讯。相比之下，Netbeans和Visual<br />
Studio的好处是设计之初就考虑到了种种高级功能之间的互相关联，所以可以做到“从数据库管理窗口里拖一个table到Web设计页面上”这样的效<br />
果。</p>
<p>Websphere的确提供了很多功能，但Websphere的使用离不开IBM自己的一堆服务端程序，感觉用Websphere做开发的人好像从来不会配合MySQL一起的。JBuilder现在也逐渐没落了，所以还是装个开源的Netbeans吧。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zhaoxiangpeng.com/2007/12/%e8%b2%8c%e4%bc%bcnetbeans-6%e6%af%94eclipse%e5%bc%ba%e5%a4%a7%e5%be%88%e5%a4%9a%e5%95%8a/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

