<?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>中文 &#187; jasonvip_c</title>
	<atom:link href="http://software.intel.com/zh-cn/blogs/author/jasonvip_c/feed/" rel="self" type="application/rss+xml" />
	<link>http://software.intel.com/zh-cn/blogs</link>
	<description></description>
	<lastBuildDate>Sat, 26 May 2012 06:34:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>多线程 BUG 捕捉之：匿名函数带来的问题</title>
		<link>http://software.intel.com/zh-cn/blogs/2010/07/05/bug/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2010/07/05/bug/#comments</comments>
		<pubDate>Mon, 05 Jul 2010 09:51:01 +0000</pubDate>
		<dc:creator>jasonvip_c</dc:creator>
				<category><![CDATA[博客征文专栏]]></category>
		<category><![CDATA[并行计算]]></category>
		<category><![CDATA[intle]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2010/07/05/bug/</guid>
		<description><![CDATA[最近有一个隐藏的BUG，是因为使用匿名函数导致的。 要重现该BUG，可以先查看如下两个程序。 第一个： class Program { static void Main(string[] args) { for (int i = 0; i &#60; 10; i++) { DisplayInt(i); } Console.Read(); } private static void DisplayInt(int i) { MethodInvoker mi = new MethodInvoker(delegate() { Thread.Sleep(1000); Console.Write(i); }); mi.BeginInvoke(null, null); } } 输出为：0 1 2 …… 9 第二个程序，采用匿名函数的方式来完成相同的功能： class Program { static void [...]]]></description>
			<content:encoded><![CDATA[<p>最近有一个隐藏的BUG，是因为使用匿名函数导致的。</p>
<p>要重现该BUG，可以先查看如下两个程序。</p>
<p>第一个：</p>
<p>class Program<br />
{<br />
static void Main(string[] args)<br />
{<br />
for (int i = 0; i &lt; 10; i++)<br />
{<br />
DisplayInt(i);<br />
}<br />
Console.Read();<br />
}</p>
<p>private static void DisplayInt(int i)<br />
{<br />
MethodInvoker mi = new MethodInvoker(delegate()<br />
{<br />
Thread.Sleep(1000);<br />
Console.Write(i);<br />
});<br />
mi.BeginInvoke(null, null);<br />
}<br />
}</p>
<p>输出为：0 1 2 …… 9</p>
<p>第二个程序，采用匿名函数的方式来完成相同的功能：</p>
<p>class Program<br />
{<br />
static void Main(string[] args)<br />
{<br />
for (int i = 0; i &lt; 10; i++)<br />
{<br />
MethodInvoker mi = new MethodInvoker(delegate()<br />
{<br />
Thread.Sleep(1000);<br />
Console.Write(i);<br />
});<br />
mi.BeginInvoke(null, null);<br />
}<br />
Console.Read();<br />
}</p>
<p>}</p>
<p>结果发现，事情并不是我们想象的那样，而是</p>
<p>输出为：10 10 10 …… 10</p>
<p>分析其原因，在第二个程序中，虽然匿名函数和第一个程序中的DisplayInt完成的是一样的功能。但是这个功能本身是要新起一个线程来执行打印i。而i这个参数，是由主线程传入进去的。那么，可以理解为，在第二个程序中，主线程中的FOR循环已经执行完毕的时候，FOR循环所起的10个工作线程，还没有启动，当它们由.NET运行时环境自行决定启动的时候（当然，这个事件会很短），FOR循环中的i已经变成10，所以，第二个程序产生了上面的结果。</p>
<p>当然，我想，这个结果应该也不唯一，这完全取决于匿名函数中的线程执行的时候FOR循环是否已经执行完毕了。</p>
<p>回过头来，考虑第一段代码，因为不是使用的匿名函数，所以内存地址中，保留了一个i的副本，故程序执行正确。</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2010/07/05/bug/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

