<?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; thy38</title>
	<atom:link href="http://software.intel.com/zh-cn/blogs/author/thy38/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>C#绝对新手之 C#中的多线程小结</title>
		<link>http://software.intel.com/zh-cn/blogs/2010/11/30/c-c/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2010/11/30/c-c/#comments</comments>
		<pubDate>Tue, 30 Nov 2010 08:13:04 +0000</pubDate>
		<dc:creator>thy38</dc:creator>
				<category><![CDATA[博客征文专栏]]></category>
		<category><![CDATA[并行计算]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2010/11/30/c-c/</guid>
		<description><![CDATA[  大概有4种方法： Dispatcher、异步委托、手动多线程、BackgroundWorker，另外还有一个DispatcherTimer，是定时器。 其中Dispatcher与DispatcherTimer相同，是利用在主线程进行任务优先级的排列来模拟多线程，因此其中实质是单线程，所以大负荷的运算不宜用它们。 BackgroundWorker会到线程池去抓一个线程作为工作线程，完成工作后切换回 UI 线程调用你定义的处理完成工作的委托。每计算出一次值，就会用worker.ReportProgress (percentComplete) 通知回调函数，并可在回调函数中更新UI。 特别适合需要更新已完成的百分比的场景。 这些都可以和数据绑定结合起来。 ①异步委托还是手动多线程 异步委托：支持线程结束时回调（BeginInvoke方法的的第一个参数），但不支持在外部中断线程，多用于更新UI。 手动线程：支持在外部中断线程（Thread.Abort方法），但不易得到函数的返回值。另外还不能更新UI。因为“Windows窗体”使用单线程单元 (STA) 模型（WPF窗体也一样），STA模型意味着可以在任何线程上创建窗口，但窗口一旦创建后就不能切换线程，并且对它的所有函数调用都必须在其创建线程上发生。特别是在注册事件的回调函数中要小心。 委托的用法： 这种调用方法和用委托对象的Invoke一样，都是同步调用，会阻塞当前线程。异步调用需要用BeginInvoke： 这里的BeginInvoke就是异步调用，运行后立即返回，不会引起当前线程的阻塞。但是在本例程中，因为newTask中要 Sleep 2秒中，如果Do Something else的时间没有2秒的话，EndInvoke还是会引起当前线程的阻塞，因为它要等待 newTask执行完毕。 那能不能不调用EndInvoke，让它自己结束呢？不太好。因为一来BeginInvoke和EndInvoke必须成对调用。即使不需要返 回值，但EndInvoke还是必须调用，否则可能会造成内存泄漏，因为它是利用了线程池资源。二来往往要调用EndInvoke 来获得函数的返回值。 如果是用BeginInvoke来进行轮询操作，EndInvoke是无法返回的，这时可以用一个变量来控制一下： 在我的应用场景里是定义了一个包装类： 要想完全与当前线程异步，可以利用BeginInvoke的第二个参数，设置一个函数执行完成后的回调函数： 这样就可以让当前线程完全没有等待的感觉了。 不过有时候，当前线程又想要利用函数执行的时间干点私活，然后在函数执行完成后再做别的，可以用WaitOne方法： （PS：用lambda语法还可以写出很炫的句子：） 其实还可以更直接： ） Invoke方法的主要功能就是帮助你在UI线程上调用委托所指定的方法。Invoke方法首先检查发出调用的线程(即当前线程 )是不是UI线程，如果是，直接执行委托指向的方法，如果不是，它将切换到UI线程，然后执行委托指向的方法。 手动线程的调用： 典型的写法是： 因为Thread调用的函数只能是无参数且无返回值的，因此通常要用类进行包装。 如果线程既需要可中断，又要与UI打交道：]]></description>
			<content:encoded><![CDATA[<p> </p>
<p>大概有4种方法：<br />
Dispatcher、异步委托、手动多线程、BackgroundWorker，另外还有一个DispatcherTimer，是定时器。</p>
<p>其中Dispatcher与DispatcherTimer相同，是利用在主线程进行任务优先级的排列来模拟多线程，因此其中实质是单线程，所以大负荷的运算不宜用它们。<br />
BackgroundWorker会到线程池去抓一个线程作为工作线程，完成工作后切换回 UI 线程调用你定义的处理完成工作的委托。每计算出一次值，就会用worker.ReportProgress (percentComplete) 通知回调函数，并可在回调函数中更新UI。</p>
<p>特别适合需要更新已完成的百分比的场景。</p>
<p>这些都可以和数据绑定结合起来。</p>
<p>①异步委托还是手动多线程<br />
异步委托：支持线程结束时回调（BeginInvoke方法的的第一个参数），但不支持在外部中断线程，多用于更新UI。</p>
<p>手动线程：支持在外部中断线程（Thread.Abort方法），但不易得到函数的返回值。另外还不能更新UI。因为“Windows窗体”使用单线程单元 (STA) 模型（WPF窗体也一样），STA模型意味着可以在任何线程上创建窗口，但窗口一旦创建后就不能切换线程，并且对它的所有函数调用都必须在其创建线程上发生。特别是在注册事件的回调函数中要小心。</p>
<p>委托的用法：<br />
<a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/11.png"><img class="alignleft size-full wp-image-400006449" src="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/11.png" alt="" width="753" height="399" /></a><br />
这种调用方法和用委托对象的Invoke一样，都是同步调用，会阻塞当前线程。异步调用需要用BeginInvoke：<br />
<a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/21.png"><img class="alignleft size-full wp-image-400006451" src="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/21.png" alt="" width="771" height="455" /></a><br />
这里的BeginInvoke就是异步调用，运行后立即返回，不会引起当前线程的阻塞。但是在本例程中，因为newTask中要</p>
<p>Sleep 2秒中，如果Do Something else的时间没有2秒的话，EndInvoke还是会引起当前线程的阻塞，因为它要等待</p>
<p>newTask执行完毕。</p>
<p>那能不能不调用EndInvoke，让它自己结束呢？不太好。因为一来BeginInvoke和EndInvoke必须成对调用。即使不需要返</p>
<p>回值，但EndInvoke还是必须调用，否则可能会造成内存泄漏，因为它是利用了线程池资源。二来往往要调用EndInvoke</p>
<p>来获得函数的返回值。</p>
<p>如果是用BeginInvoke来进行轮询操作，EndInvoke是无法返回的，这时可以用一个变量来控制一下：<br />
在我的应用场景里是定义了一个包装类：<br />
<a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/31.png"><img class="alignleft size-full wp-image-400006452" src="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/31.png" alt="" width="766" height="760" /></a><br />
要想完全与当前线程异步，可以利用BeginInvoke的第二个参数，设置一个函数执行完成后的回调函数：<br />
<a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/41.png"><img class="alignleft size-full wp-image-400006453" src="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/41.png" alt="" width="734" height="331" /></a><br />
这样就可以让当前线程完全没有等待的感觉了。</p>
<p>不过有时候，当前线程又想要利用函数执行的时间干点私活，然后在函数执行完成后再做别的，可以用WaitOne方法：<br />
<a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/51.png"><img class="alignleft size-full wp-image-400006454" src="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/51.png" alt="" width="726" height="799" /></a><br />
（PS：用lambda语法还可以写出很炫的句子：）<br />
<a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/62.png"><img class="alignleft size-full wp-image-400006461" src="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/62.png" alt="" width="761" height="60" /></a><br />
其实还可以更直接：<br />
<a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/71.png"><img class="alignleft size-full wp-image-400006462" src="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/71.png" alt="" width="753" height="45" /></a><br />
）</p>
<p>Invoke方法的主要功能就是帮助你在UI线程上调用委托所指定的方法。Invoke方法首先检查发出调用的线程(即当前线程</p>
<p>)是不是UI线程，如果是，直接执行委托指向的方法，如果不是，它将切换到UI线程，然后执行委托指向的方法。</p>
<p>手动线程的调用：<br />
典型的写法是：<br />
<a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/81.png"><img class="alignleft size-full wp-image-400006458" src="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/81.png" alt="" width="764" height="315" /></a><br />
因为Thread调用的函数只能是无参数且无返回值的，因此通常要用类进行包装。</p>
<p>如果线程既需要可中断，又要与UI打交道：<br />
<a href="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/9.png"><img class="alignleft size-full wp-image-400006459" src="http://software.intel.com/zh-cn/blogs/wordpress/wp-content/uploads/2010/11/9.png" alt="" width="771" height="349" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2010/11/30/c-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

