<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_一线码农</title><subtitle type="text"/><id>http://feed.cnblogs.com/blog/u/85195/rss</id><updated>2012-05-27T12:40:57Z</updated><author><name>一线码农</name><uri>http://www.cnblogs.com/huangxincheng/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangxincheng/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/85195/rss"/><entry><id>http://www.cnblogs.com/huangxincheng/archive/2012/05/26/2519205.html</id><title type="text">8天玩转并行开发——第六天 异步编程模型</title><summary type="text">在.net里面异步编程模型由来已久，相信大家也知道Begin/End异步模式和事件异步模式，在task出现以后，这些东西都可以被task包装起来，可能有人会问，这样做有什么好处，下面一一道来。一： Begin/End模式1： 委托 在执行委托方法的时候，我们常常会看到一个Invoke，同时也有一对你或许不常使用的BeginInvoke，EndInvoke方法对，当然Invoke方法是阻塞主线程，而BeginInvoke则是另开一个线程。 1 class Program 2 { 3 static void Main(string[] args) 4 ...</summary><published>2012-05-26T05:21:00Z</published><updated>2012-05-26T05:21:00Z</updated><author><name>一线码农</name><uri>http://www.cnblogs.com/huangxincheng/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangxincheng/archive/2012/05/26/2519205.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangxincheng/archive/2012/05/26/2519205.html"/><content type="html">&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 在.net里面异步编程模型由来已久，相信大家也知道Begin/End异步模式和事件异步模式，在task出现以后，这些东西都可以被task包装&lt;/p&gt;&lt;p&gt;起来，可能有人会问，这样做有什么好处，下面一一道来。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;一： Begin/End模式&lt;/p&gt;&lt;p&gt;1： 委托&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; 在执行委托方法的时候，我们常常会看到一个Invoke，同时也有一对你或许不常使用的BeginInvoke，EndInvoke方法对，当然Invoke方法&lt;/p&gt;&lt;p&gt;是阻塞主线程，而BeginInvoke则是另开一个线程。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] args)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; func = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Func&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt;(i =&amp;gt; { &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; i + &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;i can fly&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;; });&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; state = func.BeginInvoke(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;yes,&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, Callback, func);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #000000;"&gt;            Console.Read();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Callback(IAsyncResult async)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; result = async.AsyncState &lt;span style="color: #0000ff;"&gt;as&lt;/span&gt; Func&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt;            Console.WriteLine(result.EndInvoke(async));&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;     }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052613171255.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;下面我们用task包装一下&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] args)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; func = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Func&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt;(i =&amp;gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;                 &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; i + &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;i can fly&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #000000;"&gt;            });&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;             Task&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt;.Factory.FromAsync(func.BeginInvoke, func.EndInvoke, &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;yes,&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;).ContinueWith&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;                 (i =&amp;gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;                {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    Console.WriteLine(i.Result);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;                });&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt;            Console.Read();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;     }&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;可以看出，task只要一句就搞定，体现了task的第一个优点：简洁。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;2：流&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; 我们发现在Stream抽象类中提供了这样两对BeginRead/EndRead,BeginWrite/EndWrite（异步读写）的方法，这样它的n多继承类都可以&lt;/p&gt;&lt;p&gt;实现异步读写，下面举个继承类FileStream的例子。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] args)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; path = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;C://1.txt&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;             FileStream fs = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileStream(path, FileMode.Open);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;             FileInfo info = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileInfo(path);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] b = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;&lt;span style="color: #000000;"&gt;[info.Length];&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; asycState = fs.BeginRead(b, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, b.Length, (result) =&amp;gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;                 &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; file = result.AsyncState &lt;span style="color: #0000ff;"&gt;as&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileStream;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;                 Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;文件内容：{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, Encoding.Default.GetString(b));&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt;                file.Close();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }, fs);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;我是主线程，我不会被阻塞！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; &lt;span style="color: #000000;"&gt;            Console.Read();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;         }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052615525267.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;我们用task包装一下&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt;    &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] args)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; path = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;C://1.txt&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;             FileStream fs = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileStream(path, FileMode.Open);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;             FileInfo info = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileInfo(path);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] b = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;&lt;span style="color: #000000;"&gt;[info.Length];&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;             Task&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&amp;gt;.Factory.FromAsync(fs.BeginRead, fs.EndRead, b, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, b.Length, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, TaskCreationOptions.None)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;                .ContinueWith&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;                 (i =&amp;gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;                {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;                     Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;文件内容：{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, Encoding.Default.GetString(b));&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt;                });&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;我是主线程，我不会被阻塞！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;span style="color: #000000;"&gt;            Console.Read();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;         }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052615540827.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;其实看到这里，我们并没有发现task还有其他的什么优点，但是深入的想一下其实并不是这么回事，task能够游刃于线程并发和同步，而原始的异步&lt;/p&gt;&lt;p&gt;编程要实现线程同步还是比较麻烦的。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;假如现在有这样的一个需求，我们需要从3个txt文件中读取字符，然后进行倒序，前提是不能阻塞主线程。如果不用task的话我可能会用工作线程&lt;/p&gt;&lt;p&gt;去监视一个bool变量来判断文件是否全部读取完毕，然后再进行倒序，我也说了，相对task来说还是比较麻烦的，这里我就用task来实现。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] b;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Main()&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] array = { &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;C://1.txt&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;C://2.txt&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;C://3.txt&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; };&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;             List&amp;lt;Task&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt;&amp;gt; taskList = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; List&amp;lt;Task&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt;&amp;gt;(&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; array)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;                taskList.Add(ReadAsyc(item));&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;             Task.Factory.ContinueWhenAll(taskList.ToArray(), i =&amp;gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;                 &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; result = &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Empty;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;                 &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;获取各个task返回的结果&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;                 &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; i)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; &lt;span style="color: #000000;"&gt;                {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;                     result +=&lt;span style="color: #000000;"&gt; item.Result;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; &lt;span style="color: #000000;"&gt;                }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;                 &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;倒序&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;                 String content = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; String(result.OrderByDescending(j =&amp;gt;&lt;span style="color: #000000;"&gt; j).ToArray());&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;                 Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;倒序结果：&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;+&lt;span style="color: #000000;"&gt;content);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt; &lt;span style="color: #000000;"&gt;            });&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;我是主线程，我不会被阻塞&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt; &lt;span style="color: #000000;"&gt;            Console.ReadKey();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;异步读取&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Task&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt; ReadAsyc(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; path)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt;             FileInfo info = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileInfo(path);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] b = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;&lt;span style="color: #000000;"&gt;[info.Length];&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt;             FileStream fs = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileStream(path, FileMode.Open);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt;             Task&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&amp;gt; task = Task&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&amp;gt;.Factory.FromAsync(fs.BeginRead, fs.EndRead, b, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, b.Length, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;, TaskCreationOptions.None);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;返回当前task的执行结果&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; task.ContinueWith(i =&amp;gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt;                 &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; i.Result &amp;gt; &lt;span style="color: #800080;"&gt;0&lt;/span&gt; ? Encoding.Default.GetString(b) : &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Empty;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }, TaskContinuationOptions.ExecuteSynchronously);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;54&lt;/span&gt;     }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052615055431.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;可以看出，task的第二个优点就是：灵活性。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这里可能就有人要问了，能不能用开多个线程用read以同步的形式读取，变相的实现文件异步读取，或许我们可能常听说程序优化后，最后出现的&lt;/p&gt;&lt;p&gt;瓶颈在IO上面，是的，IO是比较耗费资源的，要命的是如果我们开的是工作线程走IO读取文件，那么该线程就会一直处于等待状态，不会再接收任&lt;/p&gt;&lt;p&gt;何的外来请求，直到线程读取到文件为止，那么我们能不能用更少的线程来应对更多的IO操作呢？答案肯定是可以的，这里就设计到了&amp;rdquo;异步IO&amp;ldquo;的&lt;/p&gt;&lt;p&gt;概念，具体内容可以参照百科：&lt;a href="http://baike.baidu.com/view/1865389.htm"&gt;http://baike.baidu.com/view/1865389.htm&lt;/a&gt;&amp;nbsp; ，有幸的是beginXXX,endXXX完美的封装了&amp;ldquo;异步IO&amp;rdquo;。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;二：事件模式&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;这个模式常以XXXCompleted的形式结尾，我们在文件下载这一块会经常遇到，这里我也举个例子。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] args)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;             WebClient client = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; WebClient();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;             client.DownloadFileCompleted += &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.ComponentModel.AsyncCompletedEventHandler(client_DownloadFileCompleted);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;             client.DownloadFileAsync(&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Uri(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://imgsrc.baidu.com/baike/abpic/item/6a600c338744ebf844a0bc74d9f9d72a6159a7ac.jpg&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;),&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;                                    &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;1.jpg&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;图片下完了，你懂的！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;我是主线程，我不会被阻塞！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;            Console.Read();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; client_DownloadFileCompleted(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; sender, System.ComponentModel.AsyncCompletedEventArgs e)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; +&lt;span style="color: #000000;"&gt; e.UserState);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;     }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052615285212.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;先前也说了，task是非常灵活的，那么针对这种异步模型，我们该如何封装成task来使用，幸好framework中提供了TaskCompletionSource来帮助&lt;/p&gt;&lt;p&gt;我们快速实现。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Collections.Generic;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Linq;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Text;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.IO;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Threading.Tasks;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Net;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.ComponentModel;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000;"&gt; ConsoleApplication4&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #000000;"&gt;{&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; Main()&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; downloadTask =&lt;span style="color: #000000;"&gt; DownLoadFileInTask(&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;                     &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Uri(&lt;span style="color: #800000;"&gt;@"&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://www.7720mm.cn/uploadfile/2010/1120/20101120073035736.jpg&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;                     , &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;C://1.jpg&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;             downloadTask.ContinueWith(i =&amp;gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;                 Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;图片:&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + i.Result + &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;下载完毕！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; &lt;span style="color: #000000;"&gt;            });&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;我是主线程，我不会被阻塞!&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; &lt;span style="color: #000000;"&gt;            Console.Read();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Task&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt; DownLoadFileInTask(Uri address, &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; saveFile)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; wc = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; WebClient();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; tcs = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; TaskCompletionSource&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt;&lt;span style="color: #000000;"&gt;(address);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;处理异步操作的一个委托&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt;             AsyncCompletedEventHandler handler = &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt;             handler = (sender, e) =&amp;gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt;                 &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (e.Error != &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt; &lt;span style="color: #000000;"&gt;                {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    tcs.TrySetException(e.Error);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt; &lt;span style="color: #000000;"&gt;                }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt;                 &lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt; &lt;span style="color: #000000;"&gt;                {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt;                     &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (e.Cancelled)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        tcs.TrySetCanceled();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt;                     &lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        tcs.TrySetResult(saveFile);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;54&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;55&lt;/span&gt; &lt;span style="color: #000000;"&gt;                }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;56&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;57&lt;/span&gt;                 wc.DownloadFileCompleted -=&lt;span style="color: #000000;"&gt; handler;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;58&lt;/span&gt; &lt;span style="color: #000000;"&gt;            };&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;59&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;60&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;我们将下载事件与我们自定义的handler进行了关联&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;61&lt;/span&gt;             wc.DownloadFileCompleted +=&lt;span style="color: #000000;"&gt; handler;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;62&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;63&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;64&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;65&lt;/span&gt; &lt;span style="color: #000000;"&gt;                wc.DownloadFileAsync(address, saveFile);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;66&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;67&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt;&lt;span style="color: #000000;"&gt; (Exception ex)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;68&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;69&lt;/span&gt;                 wc.DownloadFileCompleted -=&lt;span style="color: #000000;"&gt; handler;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;70&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;71&lt;/span&gt; &lt;span style="color: #000000;"&gt;                tcs.TrySetException(ex);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;72&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;73&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;74&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; tcs.Task;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;75&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;76&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;77&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052615475516.png" alt="" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangxincheng/aggbug/2519205.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangxincheng/archive/2012/05/26/2519205.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangxincheng/archive/2012/05/20/2509715.html</id><title type="text">12篇学通C#网络编程——第三篇 HTTP应用编程（下）</title><summary type="text">第三篇来的好晚啊，上一篇说了如何向服务器推送信息，这一篇我们看看如何"快好准"的从服务器下拉信息。 网络上有很多大资源文件，比如供人下载的zip包，电影（你懂的），那么我们如何快速的进行下载，大家第一反应肯定就是多线程下载，那么这些东西是如何做的呢？首先我们可以从“QQ的中转站里面拉一个rar下来“。然后用fiddler监视一下，我们会发现一个有趣的现象：第一：7.62*1024*1024≈7990914 千真万确是此文件第二：我明明是一个http链接，tmd的怎么变成n多个了？有意思。好，我们继续往下看，看看这些链接都做了些什么？最终，我们发现http协议中有一个Cone</summary><published>2012-05-20T05:42:00Z</published><updated>2012-05-20T05:42:00Z</updated><author><name>一线码农</name><uri>http://www.cnblogs.com/huangxincheng/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangxincheng/archive/2012/05/20/2509715.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangxincheng/archive/2012/05/20/2509715.html"/><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; 第三篇来的好晚啊，上一篇说了如何向服务器推送信息，这一篇我们看看如何"快好准"的从服务器下拉信息。&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; 网络上有很多大资源文件，比如供人下载的zip包，电影（你懂的），那么我们如何快速的进行下载，大家第一反应肯定就是多线程下载，&lt;/p&gt;&lt;p&gt;那么这些东西是如何做的呢？首先我们可以从&amp;ldquo;QQ的中转站里面拉一个rar下来&amp;ldquo;。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052011482054.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;然后用fiddler监视一下，我们会发现一个有趣的现象：&lt;/p&gt;&lt;p&gt;第一：7.62*1024*1024&amp;asymp;7990914 &amp;nbsp;千真万确是此文件&lt;/p&gt;&lt;p&gt;第二：我明明是一个http链接，tmd的怎么变成n多个了？有意思。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052012003642.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;好，我们继续往下看，看看这些链接都做了些什么？&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052012013728.png" alt="" /&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052012020281.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;最终，我们发现http协议中有一个Conent&amp;mdash;Range字段，能够把我们的文件总大小进行切分，然后并行下载，最后再进行合并，大概我们知道&lt;/p&gt;&lt;p&gt;了什么原理，那么，我们强大的C#类库提供了AddRange来获取Http中资源的指定范围。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;既然进行了切分，那么首先一定要知道文件的ContentLength是多少，如果对http协议比较熟悉的话，当发送一个头信息过去，服务器返回的&lt;/p&gt;&lt;p&gt;头信息中会包含很多东西，此时我们就知道要下载资源的大概情况，这个就有点&amp;ldquo;兵马未动，粮草先行&amp;ldquo;的感觉。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052012180080.png" alt="" /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; request =&lt;span style="color: #000000;"&gt; (HttpWebRequest)HttpWebRequest.Create(url);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;             request.Method = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Head&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;             request.Timeout = &lt;span style="color: #800080;"&gt;3000&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; response =&lt;span style="color: #000000;"&gt; (HttpWebResponse)request.GetResponse();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; code =&lt;span style="color: #000000;"&gt; response.StatusCode;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (code !=&lt;span style="color: #000000;"&gt; HttpStatusCode.OK)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;                 Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;下载资源无效！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;                 &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; total = response.ContentLength;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;这里有个决策，到底是以下载量来决定线程数，还是以线程数来决定下载量，由于我们的下载取决于当前的网速，所以在这种场合下更好的方案是&lt;/p&gt;&lt;p&gt;采用后者，这几天在闪存里面两次看到苍老师，肃然起敬，所以决定在不用线程和线程的情况下，看看下载仓老师的速度如何。&lt;/p&gt;&lt;p&gt;图片大小(217.27KB)&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;" onclick="cnblogs_code_show('702ce1e4-41a3-4f7e-ab40-fe63458709ae')"&gt;&lt;div id="cnblogs_code_open_702ce1e4-41a3-4f7e-ab40-fe63458709ae" class="cnblogs_code_hide"&gt;&lt;span style="color: #008080;"&gt;  1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Collections.Generic;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Linq;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Text;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Net;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Threading;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Threading.Tasks;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  8&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.IO;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;  9&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Collections.Concurrent;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 10&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Diagnostics;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 11&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Drawing;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 12&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 13&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 14&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000;"&gt; ConsoleApplication1&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 15&lt;/span&gt; &lt;span style="color: #000000;"&gt;{&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 16&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 17&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 18&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; CountdownEvent cde = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; CountdownEvent(&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 19&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 20&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;每个线程下载的字节数，方便最后合并&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt; 21&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; ConcurrentDictionary&amp;lt;&lt;span style="color: #0000ff;"&gt;long&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[]&amp;gt; dic = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ConcurrentDictionary&amp;lt;&lt;span style="color: #0000ff;"&gt;long&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[]&amp;gt;&lt;span style="color: #000000;"&gt;();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 22&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 23&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;请求文件&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt; 24&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; url = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://www.pncity.net/bbs/data/attachment/forum/201107/30/1901108yyd8gnrs2isadrr.jpg&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 25&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 26&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] args)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 27&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 28&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; i = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; i &amp;lt; &lt;span style="color: #800080;"&gt;1&lt;/span&gt;; i++&lt;span style="color: #000000;"&gt;)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 29&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 30&lt;/span&gt;                 Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n****************************\n第{0}次比较\n****************************&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, (i + &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;));&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 31&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 32&lt;/span&gt;                 &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;不用线程&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 33&lt;/span&gt;                 &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;RunSingle();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 34&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 35&lt;/span&gt;                 &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;使用多线程&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt; 36&lt;/span&gt; &lt;span style="color: #000000;"&gt;                RunMultiTask();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 37&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 38&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 39&lt;/span&gt; &lt;span style="color: #000000;"&gt;            Console.Read();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 40&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 41&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 42&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; RunMultiTask()&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 43&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 44&lt;/span&gt;             Stopwatch watch =&lt;span style="color: #000000;"&gt; Stopwatch.StartNew();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 45&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 46&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;开5个线程&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt; 47&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; threadCount = &lt;span style="color: #800080;"&gt;5&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 48&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 49&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;long&lt;/span&gt; start = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 50&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 51&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;long&lt;/span&gt; end = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 52&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 53&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; total =&lt;span style="color: #000000;"&gt; GetSourceHead();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 54&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 55&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (total == &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 56&lt;/span&gt;                 &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 57&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 58&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; pageSize = (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;)Math.Ceiling((Double)total /&lt;span style="color: #000000;"&gt; threadCount);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 59&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 60&lt;/span&gt; &lt;span style="color: #000000;"&gt;            cde.Reset(threadCount);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 61&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 62&lt;/span&gt;             Task[] tasks = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Task[threadCount];&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 63&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 64&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; i = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; i &amp;lt; threadCount; i++&lt;span style="color: #000000;"&gt;)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 65&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 66&lt;/span&gt;                 start = i *&lt;span style="color: #000000;"&gt; pageSize;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 67&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 68&lt;/span&gt;                 end = (i + &lt;span style="color: #800080;"&gt;1&lt;/span&gt;) * pageSize - &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 69&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 70&lt;/span&gt;                 &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (end &amp;gt;&lt;span style="color: #000000;"&gt; total)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 71&lt;/span&gt;                     end =&lt;span style="color: #000000;"&gt; total;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 72&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 73&lt;/span&gt;                 &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; obj = start + &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;|&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; +&lt;span style="color: #000000;"&gt; end;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 74&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 75&lt;/span&gt;                 tasks[i] = Task.Factory.StartNew(j =&amp;gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; DownFile().DownTaskMulti(obj), obj);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 76&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 77&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 78&lt;/span&gt; &lt;span style="color: #000000;"&gt;            Task.WaitAll(tasks);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 79&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 80&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; targetFile = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;C://&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + url.Substring(url.LastIndexOf(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;) + &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 81&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 82&lt;/span&gt;             FileStream fs = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileStream(targetFile, FileMode.Create);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 83&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 84&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; result = dic.Keys.OrderBy(i =&amp;gt;&lt;span style="color: #000000;"&gt; i).ToList();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 85&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 86&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; item &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; result)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 87&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 88&lt;/span&gt;                 fs.Write(dic[item], &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, dic[item].Length);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 89&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 90&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 91&lt;/span&gt; &lt;span style="color: #000000;"&gt;            fs.Close();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 92&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 93&lt;/span&gt; &lt;span style="color: #000000;"&gt;            watch.Stop();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 94&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 95&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;多线程：下载耗费时间:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, watch.Elapsed);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 96&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 97&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt; 98&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; RunSingle()&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 99&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;100&lt;/span&gt;             Stopwatch watch =&lt;span style="color: #000000;"&gt; Stopwatch.StartNew();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;101&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;102&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (GetSourceHead() == &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;103&lt;/span&gt;                 &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;104&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;105&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; request =&lt;span style="color: #000000;"&gt; (HttpWebRequest)HttpWebRequest.Create(url);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;106&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;107&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; response =&lt;span style="color: #000000;"&gt; (HttpWebResponse)request.GetResponse();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;108&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;109&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; stream =&lt;span style="color: #000000;"&gt; response.GetResponseStream();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;110&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;111&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; outStream = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MemoryStream();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;112&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;113&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; bytes = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[&lt;span style="color: #800080;"&gt;10240&lt;/span&gt;&lt;span style="color: #000000;"&gt;];&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;114&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;115&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; count = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;116&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;117&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;while&lt;/span&gt; ((count = stream.Read(bytes, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, bytes.Length)) != &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;118&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;119&lt;/span&gt;                 outStream.Write(bytes, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, count);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;120&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;121&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;122&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; targetFile = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;C://&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + url.Substring(url.LastIndexOf(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;) + &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;123&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;124&lt;/span&gt;             FileStream fs = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; FileStream(targetFile, FileMode.Create);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;125&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;126&lt;/span&gt;             fs.Write(outStream.ToArray(), &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt;)outStream.Length);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;127&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;128&lt;/span&gt; &lt;span style="color: #000000;"&gt;            outStream.Close();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;129&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;130&lt;/span&gt; &lt;span style="color: #000000;"&gt;            response.Close();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;131&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;132&lt;/span&gt; &lt;span style="color: #000000;"&gt;            fs.Close();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;133&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;134&lt;/span&gt; &lt;span style="color: #000000;"&gt;            watch.Stop();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;135&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;136&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;不用线程：下载耗费时间:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, watch.Elapsed);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;137&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;138&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;139&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;获取头信息&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;140&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;long&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetSourceHead()&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;141&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;142&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; request =&lt;span style="color: #000000;"&gt; (HttpWebRequest)HttpWebRequest.Create(url);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;143&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;144&lt;/span&gt;             request.Method = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Head&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;145&lt;/span&gt;             request.Timeout = &lt;span style="color: #800080;"&gt;3000&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;146&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;147&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; response =&lt;span style="color: #000000;"&gt; (HttpWebResponse)request.GetResponse();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;148&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;149&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; code =&lt;span style="color: #000000;"&gt; response.StatusCode;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;150&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;151&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (code !=&lt;span style="color: #000000;"&gt; HttpStatusCode.OK)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;152&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;153&lt;/span&gt;                 Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;下载的资源无效！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;154&lt;/span&gt;                 &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;155&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;156&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;157&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; total =&lt;span style="color: #000000;"&gt; response.ContentLength;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;158&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;159&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前资源大小为:&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; +&lt;span style="color: #000000;"&gt; total);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;160&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;161&lt;/span&gt; &lt;span style="color: #000000;"&gt;            response.Close();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;162&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;163&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; total;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;164&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;165&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;166&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;167&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; DownFile&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;168&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;169&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 多线程下载&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;170&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; DownTaskMulti(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; obj)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;171&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;172&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; single = obj.ToString().Split(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;|&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;173&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;174&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;long&lt;/span&gt; start =&lt;span style="color: #000000;"&gt; Convert.ToInt64(single.FirstOrDefault());&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;175&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;176&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;long&lt;/span&gt; end =&lt;span style="color: #000000;"&gt; Convert.ToInt64(single.LastOrDefault());&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;177&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;178&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; request =&lt;span style="color: #000000;"&gt; (HttpWebRequest)HttpWebRequest.Create(Program.url);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;179&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;180&lt;/span&gt; &lt;span style="color: #000000;"&gt;            request.AddRange(start, end);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;181&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;182&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; response =&lt;span style="color: #000000;"&gt; (HttpWebResponse)request.GetResponse();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;183&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;184&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; stream =&lt;span style="color: #000000;"&gt; response.GetResponseStream();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;185&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;186&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; outStream = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MemoryStream();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;187&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;188&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; bytes = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[&lt;span style="color: #800080;"&gt;10240&lt;/span&gt;&lt;span style="color: #000000;"&gt;];&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;189&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;190&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; count = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;191&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;192&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;while&lt;/span&gt; ((count = stream.Read(bytes, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, bytes.Length)) != &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;193&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;194&lt;/span&gt;                 outStream.Write(bytes, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;, count);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;195&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;196&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;197&lt;/span&gt; &lt;span style="color: #000000;"&gt;            outStream.Close();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;198&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;199&lt;/span&gt; &lt;span style="color: #000000;"&gt;            response.Close();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;200&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;201&lt;/span&gt; &lt;span style="color: #000000;"&gt;            Program.dic.TryAdd(start, outStream.ToArray());&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;202&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;203&lt;/span&gt; &lt;span style="color: #000000;"&gt;            Program.cde.Signal();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;204&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;205&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;206&lt;/span&gt; }&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052013073981.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052013503611.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052013504512.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052013505053.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 在下面的图中可以看出，我们的资源被分成了n段，在217.27KB的情况下，多线程加速还不是很明显，我们可以试试更大的文件，这里我就&lt;/p&gt;&lt;p&gt;在本地放一个133M的rar文件。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;请求文件&lt;/span&gt;&lt;br/&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; url = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://localhost:56933/1.rar&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;;&lt;/div&gt;&lt;p&gt;现在看一下效果是非常明显的。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012052013190281.png" alt="" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangxincheng/aggbug/2509715.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangxincheng/archive/2012/05/20/2509715.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangxincheng/archive/2012/05/13/2497738.html</id><title type="text">lucene，你也会(7篇）——第一篇 快速入门</title><summary type="text">日常开发中，相信大家经常会用like去匹配一些数据，同时我们也知道，like往往会导致全表扫描，当数据量越来越大的时候，我们会纠结于数据库的龟速查找，此时我们必须另寻蹊跷，这时lucene就可以大显身手了。 首先我们做一个demo，向数据库中插入10w条数据，总共778M。接下来，我们搜索下新闻内容中包含“流行”的记录。mmd，检索一下要78s，是谁都要砸了面前的破机子。下面我们来看看lucene的效果怎么样。下载地址：http://incubator.apache.org/lucene.net/download.html 1 using System; 2 using Syste...</summary><published>2012-05-12T16:53:00Z</published><updated>2012-05-12T16:53:00Z</updated><author><name>一线码农</name><uri>http://www.cnblogs.com/huangxincheng/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangxincheng/archive/2012/05/13/2497738.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangxincheng/archive/2012/05/13/2497738.html"/><content type="html">&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 日常开发中，相信大家经常会用like去匹配一些数据，同时我们也知道，like往往会导致全表扫描，当数据量越来越大的时候，我们会纠结于&lt;/p&gt;&lt;p&gt;数据库的龟速查找，此时我们必须另寻蹊跷，这时lucene就可以大显身手了。&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;首先我们做一个demo，向数据库中插入10w条数据，总共778M。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012051222570074.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;接下来，我们搜索下新闻内容中包含&amp;ldquo;&lt;span style="color: #ff0000;"&gt;流行&lt;/span&gt;&amp;rdquo;的&lt;span style="color: #000000;"&gt;记录。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012051223113916.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;mmd，检索一下要78s，是谁都要砸了面前的破机子。&lt;/p&gt;&lt;p&gt;下面我们来看看lucene的效果怎么样。下载地址：&lt;a href="http://incubator.apache.org/lucene.net/download.html"&gt;http://incubator.apache.org/lucene.net/download.html&lt;/a&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Collections.Generic;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Linq;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Text;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Lucene.Net.Index;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Lucene.Net.Store;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Lucene.Net.Analysis.Standard;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Lucene.Net.Documents;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Data;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; System.Diagnostics;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Lucene.Net.Search;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;span style="color: #000000;"&gt; Lucene.Net.QueryParsers;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000;"&gt; First&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt;{&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; Program&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; path = &lt;span style="color: #800000;"&gt;@"&lt;/span&gt;&lt;span style="color: #800000;"&gt;D:\Sample&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] args)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;创建索引&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; &lt;span style="color: #000000;"&gt;            CreateIndex();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; watch =&lt;span style="color: #000000;"&gt; Stopwatch.StartNew();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;搜索&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;             IndexSearcher search = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; IndexSearcher(path);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;查询表达式&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;             QueryParser query = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; QueryParser(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;.Empty, &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; StandardAnalyzer());&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;query.parse：注入查询条件&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; hits = search.Search(query.Parse(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Content:流行&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;));&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; i = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; i &amp;lt; hits.Length(); i++&lt;span style="color: #000000;"&gt;)&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt;                 Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前内容:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, hits.Doc(i).Get(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Content&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;).Substring(&lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #800080;"&gt;20&lt;/span&gt;) + &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;...&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt; &lt;span style="color: #000000;"&gt;            watch.Stop();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;搜索耗费时间:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;, watch.ElapsedMilliseconds);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; CreateIndex()&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;创建索引库目录&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; directory = FSDirectory.GetDirectory(path, &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;创建一个索引,采用StandardAnalyzer对句子进行分词&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt;             IndexWriter indexWriter = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; IndexWriter(directory, &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; StandardAnalyzer());&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;54&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;55&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; reader = DbHelperSQL.ExecuteReader(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;select * from News&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;56&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;57&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;while&lt;/span&gt;&lt;span style="color: #000000;"&gt; (reader.Read())&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;58&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;59&lt;/span&gt;                 &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;域的集合：文档，类似于表的行&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;60&lt;/span&gt;                 Document doc = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Document();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;61&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;62&lt;/span&gt;                 &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;要索引的字段&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;63&lt;/span&gt;                 doc.Add(&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Field(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;ID&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, reader[&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;ID&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;64&lt;/span&gt;                 doc.Add(&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Field(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Title&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, reader[&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Title&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToString(), Field.Store.NO, Field.Index.ANALYZED));&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;65&lt;/span&gt;                 doc.Add(&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Field(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Content&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, reader[&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Content&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;].ToString(), Field.Store.YES, Field.Index.ANALYZED));&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;66&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;67&lt;/span&gt; &lt;span style="color: #000000;"&gt;                indexWriter.AddDocument(doc);&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;68&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;69&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;70&lt;/span&gt; &lt;span style="color: #000000;"&gt;            reader.Close();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;71&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;72&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;对索引文件进行优化&lt;/span&gt;&lt;br/&gt;&lt;span style="color: #008080;"&gt;73&lt;/span&gt; &lt;span style="color: #000000;"&gt;            indexWriter.Optimize();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;74&lt;/span&gt; &lt;br/&gt;&lt;span style="color: #008080;"&gt;75&lt;/span&gt; &lt;span style="color: #000000;"&gt;            indexWriter.Close();&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;76&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;77&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }&lt;br/&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;78&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012051300082744.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;我靠，448ms，顿时78s黯然失色，当然这个时间是不包含"创建索引&amp;ldquo;的时间，从时间复杂度上来说，这种预加载索引算是常量。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;作为入门，简单的介绍下lucene的实现过程，首先lucene主要分成两步："索引"和"搜索"。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;一：索引：&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;相信大家对索引还是比较熟悉的，lucene能够将我们内容切分成很多词，然后将词作为key，建立&amp;ldquo;倒排索引&amp;rdquo;，然后放到索引库中，在上面&lt;/span&gt;&lt;/p&gt;&lt;p&gt;的例子中，我们看到了索引过程中使用到了IndexWriter，FSDirectory，StandardAnalyzer，Document和Field这些类，下面简要分析下。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;1：IndexWriter&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; 我们看到该类有一个AddDocument方法，所以我们认为该类实现了索引的写入操作。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;2：FSDirectory&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; 这个就更简单了，提供了索引库的存放位置，比如我们这里的D:\Sample，或许有人问，能不能存放在内存中，在强大的lucene面前当然&lt;/p&gt;&lt;p&gt;可以做到，lucene中的RAMDirectory就可以实现，当然我们的内存足够大的话，还是可以用内存承载索引库，进而提高搜索的效率。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;3：StandardAnalyzer&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;这个算是索引过程中最最关键的一步，也是我们使用lucene非常慎重考虑的东西，之所以我们能搜索秒杀，关键在于我们如何将输入的内容&lt;/p&gt;&lt;p&gt;进行何种形式的切分，当然不同的切分形式诞生了不同的分析器，StandardAnalyzer就是一个按照单字分词的一种分析器，详细的介绍后续文&lt;/p&gt;&lt;p&gt;章分享。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;4：Document&lt;/p&gt;&lt;p&gt;&amp;nbsp;在上面的例子可以看到，他是承载field的集合，然后添加到IndexWriter中，有点类似表中的行的概念。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;5: Field&lt;/p&gt;&lt;p&gt;提供了对要分析的字段进行何种处理，以KV形式呈现。&lt;/p&gt;&lt;p&gt;①：Field.Store.YES，&amp;nbsp;Field.Index.NOT_ANALYZED &amp;nbsp; 表示对索引字段采取：原样保存并且不被StandardAnalyzer进行切分。&lt;/p&gt;&lt;p&gt;②：&amp;nbsp;Field.Store.NO, Field.Index.ANALYZED &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 不保存但是要被StandardAnalyzer切分。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;二：搜索&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;这个比较容易，根据我们输入的词lucene能够在索引库中快速定位到我们要找的词，同样我们可以看到IndexSearcher，QueryParser，Hits。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;1：IndexSearcher&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp; &amp;nbsp;这个我们可以理解成以只读的形式打开由IndexWriter创建的索引库，search给QueryParser提供了查询的桥梁。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;2：QueryParser&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp; &amp;nbsp;这玩意提供了一个parse方法能够将我们要查找的词转化为lucene能够理解了查询表达式。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;3：Hits&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp; &amp;nbsp;这个就是获取匹配结果的一个指针，优点类似C#中的延迟加载，目的都是一样，提高性能。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;好了，大体上也就这样，时间不早了，洗洗睡了。嘻嘻。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangxincheng/aggbug/2497738.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangxincheng/archive/2012/05/13/2497738.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangxincheng/archive/2012/04/08/2437701.html</id><title type="text">8天玩转并行开发——第五天 同步机制（下）</title><summary type="text">承接上一篇，我们继续说下.net4.0中的同步机制，是的，当出现了并行计算的时候，轻量级别的同步机制应运而生，在信号量这一块出现了一系列的轻量级，今天继续介绍下面的3个信号量CountdownEvent，SemaphoreSlim，ManualResetEventSlim。一：CountdownEvent 这种采用信号状态的同步基元非常适合在动态的fork,join的场景，它采用“信号计数”的方式，就比如这样，一个麻将桌只能容纳4个人打麻将，如果后来的人也想搓一把碰碰运气，那么他必须等待直到麻将桌上的人走掉一位。好，这就是简单的信号计数机制，从技术角度上来说它是定义了最多能够进入关键代...</summary><published>2012-04-08T07:53:00Z</published><updated>2012-04-08T07:53:00Z</updated><author><name>一线码农</name><uri>http://www.cnblogs.com/huangxincheng/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangxincheng/archive/2012/04/08/2437701.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangxincheng/archive/2012/04/08/2437701.html"/><content type="html">&lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;承接上一篇，我们继续说下.net4.0中的同步机制，是的，当出现了并行计算的时候，轻量级别的同步机制应运而生，在信号量这一块&lt;/p&gt;&lt;p&gt;出现了一系列的轻量级，今天继续介绍下面的3个信号量&amp;nbsp;CountdownEvent，SemaphoreSlim，ManualResetEventSlim。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;一：CountdownEvent&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;这种采用信号状态的同步基元非常适合在动态的fork,join的场景，它采用&amp;ldquo;信号计数&amp;rdquo;的方式，就比如这样，一个麻将桌只能容纳4个&lt;/p&gt;&lt;p&gt;人打麻将，如果后来的人也想搓一把碰碰运气，那么他必须等待直到麻将桌上的人走掉一位。好，这就是简单的信号计数机制，从技术角&lt;/p&gt;&lt;p&gt;度上来说它是定义了最多能够进入关键代码的线程数。&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;但是CountdownEvent更牛X之处在于我们可以动态的改变&amp;ldquo;信号计数&amp;rdquo;的大小，比如一会儿能够容纳8个线程，一下又4个，一下又10个，&lt;/p&gt;&lt;p&gt;这样做有什么好处呢？还是承接上一篇文章所说的，比如一个任务需要加载1w条数据，那么可能出现这种情况。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;加载User表： &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 根据user表的数据量，我们需要开5个task。&lt;/p&gt;&lt;p&gt;加载Product表： &amp;nbsp; &amp;nbsp;产品表数据相对比较多，计算之后需要开8个task。&lt;/p&gt;&lt;p&gt;加载order表： &amp;nbsp; &amp;nbsp; &amp;nbsp; 由于我的网站订单丰富，计算之后需要开12个task。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;先前的文章也说了，我们需要协调task在多阶段加载数据的同步问题，那么如何应对这里的5，8，12，幸好，CountdownEvent给我们提供了&lt;/p&gt;&lt;p&gt;可以动态修改的解决方案。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;  1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Concurrent;&lt;br /&gt;&lt;span style="color: #008080;"&gt;  2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #008080;"&gt;  3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #008080;"&gt;  4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #008080;"&gt;  5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #008080;"&gt;  6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span style="color: #008080;"&gt;  7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;span style="color: #008080;"&gt;  8&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;  9&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 10&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 11&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;默认的容纳大小为&amp;ldquo;硬件线程&amp;ldquo;数&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 12&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; CountdownEvent cde = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; CountdownEvent(Environment.ProcessorCount);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 14&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 15&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 16&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;加载User表需要5个任务&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 17&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; userTaskCount = &lt;span style="color: #800080;"&gt;5&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 18&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 19&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;重置信号&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 20&lt;/span&gt; cde.Reset(userTaskCount);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 21&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 22&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; i = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; i &amp;lt; userTaskCount; i++)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 23&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 24&lt;/span&gt; Task.Factory.StartNew((obj) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 25&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 26&lt;/span&gt; LoadUser(obj);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 27&lt;/span&gt; }, i);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 28&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 29&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 30&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;等待所有任务执行完毕&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 31&lt;/span&gt; cde.Wait();&lt;br /&gt;&lt;span style="color: #008080;"&gt; 32&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 33&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\nUser表数据全部加载完毕！\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 34&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 35&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;加载product需要8个任务&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 36&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; productTaskCount = &lt;span style="color: #800080;"&gt;8&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 37&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 38&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;重置信号&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 39&lt;/span&gt; cde.Reset(productTaskCount);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 40&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 41&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; i = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; i &amp;lt; productTaskCount; i++)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 42&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 43&lt;/span&gt; Task.Factory.StartNew((obj) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 44&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 45&lt;/span&gt; LoadProduct(obj);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 46&lt;/span&gt; }, i);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 47&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 48&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 49&lt;/span&gt; cde.Wait();&lt;br /&gt;&lt;span style="color: #008080;"&gt; 50&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 51&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\nProduct表数据全部加载完毕！\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 52&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 53&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;加载order需要12个任务&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 54&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; orderTaskCount = &lt;span style="color: #800080;"&gt;12&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 55&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 56&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;重置信号&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 57&lt;/span&gt; cde.Reset(orderTaskCount);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 58&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 59&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; i = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; i &amp;lt; orderTaskCount; i++)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 60&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 61&lt;/span&gt; Task.Factory.StartNew((obj) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 62&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 63&lt;/span&gt; LoadOrder(obj);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 64&lt;/span&gt; }, i);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 65&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 66&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 67&lt;/span&gt; cde.Wait();&lt;br /&gt;&lt;span style="color: #008080;"&gt; 68&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 69&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\nOrder表数据全部加载完毕！\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 70&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 71&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n(*^__^*) 嘻嘻，恭喜你，数据全部加载完毕\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 72&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 73&lt;/span&gt; Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt; 74&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 75&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 76&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; LoadUser(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; obj)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 77&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 78&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 79&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 80&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前任务:{0}正在加载User部分数据！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, obj);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 81&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 82&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;finally&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 83&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 84&lt;/span&gt; cde.Signal();&lt;br /&gt;&lt;span style="color: #008080;"&gt; 85&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 86&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 87&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 88&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; LoadProduct(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; obj)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 89&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 90&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 91&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 92&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前任务:{0}正在加载Product部分数据！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, obj);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 93&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 94&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;finally&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 95&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 96&lt;/span&gt; cde.Signal();&lt;br /&gt;&lt;span style="color: #008080;"&gt; 97&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 98&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 99&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;100&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; LoadOrder(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; obj)&lt;br /&gt;&lt;span style="color: #008080;"&gt;101&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;102&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;103&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;104&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前任务:{0}正在加载Order部分数据！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, obj);&lt;br /&gt;&lt;span style="color: #008080;"&gt;105&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;106&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;finally&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;107&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;108&lt;/span&gt; cde.Signal();&lt;br /&gt;&lt;span style="color: #008080;"&gt;109&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;110&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;111&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040815045091.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;我们看到有两个主要方法：Wait和Signal。每调用一次Signal相当于麻将桌上走了一个人，直到所有人都搓过麻将wait才给放行，这里同样要&lt;/p&gt;&lt;p&gt;注意也就是&amp;ldquo;超时&amp;ldquo;问题的存在性，尤其是在并行计算中，轻量级别给我们提供了&amp;rdquo;取消标记&amp;ldquo;的机制，这是在重量级别中不存在的，比如下面的&lt;/p&gt;&lt;p&gt;重载public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)，具体使用可以看前一篇文章的介绍。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;二：SemaphoreSlim&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;在.net 4.0之前，framework中有一个重量级的Semaphore，人家可以跨进程同步，咋轻量级不行，msdn对它的解释为：&lt;span style="color: #ff0000;"&gt;限制可同时访问&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;某一资源或资源池的线程数&lt;/span&gt;。关于它的重量级demo，我的上一个系列有演示，你也可以理解为CountdownEvent是 SemaphoreSlim的功能加&lt;/p&gt;&lt;p&gt;强版，好了，举一个轻量级使用的例子。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Concurrent;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; SemaphoreSlim slim = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; SemaphoreSlim(Environment.ProcessorCount, &lt;span style="color: #800080;"&gt;12&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; i = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; i &amp;lt; &lt;span style="color: #800080;"&gt;12&lt;/span&gt;; i++)&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; Task.Factory.StartNew((obj) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; Run(obj);&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; }, i);&lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; obj)&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; slim.Wait();&lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前时间:{0}任务 {1}已经进入。&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, DateTime.Now, obj);&lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;这里busy3s中&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; Thread.Sleep(&lt;span style="color: #800080;"&gt;3000&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt; slim.Release();&lt;br /&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040815245786.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;同样，防止死锁的情况，我们需要知道&amp;rdquo;超时和取消标记&amp;ldquo;的解决方案，像SemaphoreSlim这种定死的&amp;rdquo;线程请求范围&amp;ldquo;，其实是降低了扩展性，&lt;/p&gt;&lt;p&gt;所以说，&lt;span style="color: #ff0000;"&gt;试水有风险&lt;/span&gt;，&lt;span style="color: #ff0000;"&gt;使用需谨慎&lt;/span&gt;，在觉得有必要的时候使用它。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;三： ManualResetEventSlim&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;相信它的重量级别大家都知道是ManualReset，而这个轻量级别采用的是"自旋等待&amp;ldquo;+&amp;rdquo;内核等待&amp;ldquo;，也就是说先采用&amp;rdquo;自旋等待的方式&amp;ldquo;等待，&lt;/p&gt;&lt;p&gt;直到另一个任务调用set方法来释放它。如果迟迟等不到释放，那么任务就会进入基于内核的等待，所以说如果我们知道等待的时间比较短，采&lt;/p&gt;&lt;p&gt;用轻量级的版本会具有更好的性能，原理大概就这样，下面举个小例子。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Concurrent;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;2047：自旋的次数&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; ManualResetEventSlim mrs = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ManualResetEventSlim(&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;, &lt;span style="color: #800080;"&gt;2047&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; i = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; i &amp;lt; &lt;span style="color: #800080;"&gt;12&lt;/span&gt;; i++)&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; Task.Factory.StartNew((obj) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; Run(obj);&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; }, i);&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前时间:{0}我是主线程{1}，你们这些任务都等2s执行吧：\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; DateTime.Now,&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; Thread.CurrentThread.ManagedThreadId);&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; Thread.Sleep(&lt;span style="color: #800080;"&gt;2000&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt; mrs.Set();&lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt; Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; obj)&lt;br /&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt; mrs.Wait();&lt;br /&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前时间:{0}任务 {1}已经进入。&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, DateTime.Now, obj);&lt;br /&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040815435036.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangxincheng/aggbug/2437701.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangxincheng/archive/2012/04/08/2437701.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangxincheng/archive/2012/04/07/2437110.html</id><title type="text">8天玩转并行开发——第四天 同步机制（上）</title><summary type="text">在并行计算中，不可避免的会碰到多个任务共享变量，实例，集合。虽然task自带了两个方法：task.ContinueWith()和Task.Factory.ContinueWhenAll()来实现任务串行化，但是这些简单的方法远远不能满足我们实际的开发需要，从.net 4.0开始，类库给我们提供了很多的类来帮助我们简化并行计算中复杂的数据同步问题。大体上分为二种：① 并发集合类: 这个在先前的文章中也用到了，他们的出现不再让我们过多的关注同步细节。② 轻量级同步机制: 相对于老版本中那些所谓的重量级同步机制而言,新的机制更加节省cpu的额外开销。关于并发集合类没什么好讲的，如...</summary><published>2012-04-07T15:07:00Z</published><updated>2012-04-07T15:07:00Z</updated><author><name>一线码农</name><uri>http://www.cnblogs.com/huangxincheng/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangxincheng/archive/2012/04/07/2437110.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangxincheng/archive/2012/04/07/2437110.html"/><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;在并行计算中，不可避免的会碰到多个任务共享变量，实例，集合。虽然task自带了两个方法：task.ContinueWith()和Task.Factory&lt;/p&gt;&lt;p&gt;.ContinueWhenAll()来实现任务串行化，但是这些简单的方法远远不能满足我们实际的开发需要，从.net 4.0开始，类库给我们提供了很多&lt;/p&gt;&lt;p&gt;的类来帮助我们简化并行计算中复杂的数据同步问题。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;大体上分为二种：&lt;/p&gt;&lt;p&gt;① &amp;nbsp; 并发集合类: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 这个在先前的文章中也用到了，他们的出现不再让我们过多的关注同步细节。&lt;/p&gt;&lt;p&gt;② &amp;nbsp;轻量级同步机制: &amp;nbsp; &amp;nbsp; &amp;nbsp;相对于老版本中那些所谓的重量级同步机制而言,新的机制更加节省cpu的额外开销。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;关于并发集合类没什么好讲的，如果大家熟悉非线程安全的集合，那么这些并发的集合对你来说小菜一碟，这一篇和下一篇我们仔细来玩玩这&lt;/p&gt;&lt;p&gt;些轻量级的同步机制。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;一：Barrier（屏障同步）&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;1：基本概念&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;msdn对它的解释是：使&lt;span style="color: #ff0000;"&gt;多个任务&lt;/span&gt;能够采用并行方式依据某种算法在&lt;span style="color: #ff0000;"&gt;多个阶段&lt;/span&gt;中&lt;span style="color: #ff0000;"&gt;协同&lt;/span&gt;工作。乍一看有点不懂，没关系，我们采取提干法。&lt;/p&gt;&lt;p&gt;&amp;rdquo;多个任务&amp;ldquo;，&amp;rdquo;多个阶段&amp;rdquo;，&amp;ldquo;协同&amp;rdquo;，仔细想想知道了，下一阶段的执行必须等待上一个阶段中多task全部执行完，那么我们实际中有这样&lt;/p&gt;&lt;p&gt;的需求吗？当然有的，比如我们数据库中有100w条数据需要导入excel，为了在数据库中加速load，我们需要开多个任务去跑，比如这&lt;/p&gt;&lt;p&gt;里的4个task，要想load产品表，必须等4个task都跑完用户表才行，那么你有什么办法可以让task为了你两肋插刀呢？它就是Barrier。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040719574218.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;好，我们知道barrier叫做屏障，就像下图中的&amp;ldquo;红色线&amp;rdquo;，如果我们的屏障设为4个task就认为已经满了的话，那么执行中先到的task必须等待&lt;/p&gt;&lt;p&gt;后到的task，通知方式也就是barrier.SignalAndWait()，屏障中线程设置操作为new Barrier(&lt;span style="color: #ff0000;"&gt;4&lt;/span&gt;,(i)=&amp;gt;{})。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040720203335.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;啰嗦了半天，还是上下代码说话：&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Concurrent;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;四个task执行&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Task[] tasks = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task[&lt;span style="color: #800080;"&gt;4&lt;/span&gt;];&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Barrier barrier = &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; barrier = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Barrier(tasks.Length, (i) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;**********************************************************&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n屏障中当前阶段编号:{0}\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, i.CurrentPhaseNumber);&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;**********************************************************&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; });&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; j = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; j &amp;lt; tasks.Length; j++)&lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; tasks[j] = Task.Factory.StartNew((obj) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; single = Convert.ToInt32(obj);&lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt; LoadUser(single);&lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt; barrier.SignalAndWait();&lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt; LoadProduct(single);&lt;br /&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt; barrier.SignalAndWait();&lt;br /&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt; LoadOrder(single);&lt;br /&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt; barrier.SignalAndWait();&lt;br /&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt; }, j);&lt;br /&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt; Task.WaitAll(tasks);&lt;br /&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;指定数据库中所有数据已经加载完毕！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt; Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; LoadUser(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; num)&lt;br /&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前任务:{0}正在加载User部分数据！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, num);&lt;br /&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;54&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; LoadProduct(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; num)&lt;br /&gt;&lt;span style="color: #008080;"&gt;55&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;56&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前任务:{0}正在加载Product部分数据！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, num);&lt;br /&gt;&lt;span style="color: #008080;"&gt;57&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;58&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;59&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; LoadOrder(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; num)&lt;br /&gt;&lt;span style="color: #008080;"&gt;60&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;61&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前任务:{0}正在加载Order部分数据！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, num);&lt;br /&gt;&lt;span style="color: #008080;"&gt;62&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;63&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040720103345.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;2：死锁问题&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; 先前的例子我们也知道，屏障必须等待4个task通过SignalAndWait()来告知自己已经到达，当4个task全部达到后，我们可以通过&lt;/p&gt;&lt;p&gt;barrier.ParticipantsRemaining来获取task到达状态，那么如果有一个task久久不能到达那会是怎样的情景呢？好，我举个例子。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Concurrent;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #008000;"&gt;//四&lt;/span&gt;&lt;span style="color: #008000;"&gt;个task执行&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Task[] tasks = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task[4];&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Barrier barrier = &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; barrier = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Barrier(tasks.Length, (i) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;**********************************************************&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n屏障中当前阶段编号:{0}\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, i.CurrentPhaseNumber);&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;**********************************************************&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; });&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; j = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; j &amp;lt; tasks.Length; j++)&lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; tasks[j] = Task.Factory.StartNew((obj) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; single = Convert.ToInt32(obj);&lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt; LoadUser(single);&lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt; barrier.SignalAndWait();&lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt; LoadProduct(single);&lt;br /&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt; barrier.SignalAndWait();&lt;br /&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt; LoadOrder(single);&lt;br /&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt; barrier.SignalAndWait();&lt;br /&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt; }, j);&lt;br /&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt; Task.WaitAll(tasks);&lt;br /&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt; barrier.Dispose();&lt;br /&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;指定数据库中所有数据已经加载完毕！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt; Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; LoadUser(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; num)&lt;br /&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;54&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n当前任务:{0}正在加载User部分数据！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, num);&lt;br /&gt;&lt;span style="color: #008080;"&gt;55&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;56&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (num == &lt;span style="color: #800080;"&gt;0&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt;57&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;58&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;num=0：表示0号任务&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;59&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;barrier.ParticipantsRemaining == 0：表示所有task到达屏障才会退出&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;60&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; SpinWait.SpinUntil: 自旋锁，相当于死循环&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;61&lt;/span&gt; SpinWait.SpinUntil(() =&amp;gt; barrier.ParticipantsRemaining == &lt;span style="color: #800080;"&gt;0&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;62&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;63&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;64&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;65&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; LoadProduct(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; num)&lt;br /&gt;&lt;span style="color: #008080;"&gt;66&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;67&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前任务:{0}正在加载Product部分数据！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, num);&lt;br /&gt;&lt;span style="color: #008080;"&gt;68&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;69&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;70&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; LoadOrder(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; num)&lt;br /&gt;&lt;span style="color: #008080;"&gt;71&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;72&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前任务:{0}正在加载Order部分数据！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, num);&lt;br /&gt;&lt;span style="color: #008080;"&gt;73&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;74&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040721085012.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;我们发现程序在加载User表的时候卡住了，出现了类似死循环，这句SpinWait.SpinUntil(() =&amp;gt; barrier.ParticipantsRemaining == 0)中&lt;/p&gt;&lt;p&gt;的ParticipantsRemaining==0&amp;nbsp;永远也不能成立，导致task0永远都不能退出，然而barrier还在一直等待task0调用SignalAndWait来结束屏障。&lt;/p&gt;&lt;p&gt;结果就是造成了相互等待的尴尬局面,我们下个断点看看情况。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040721101450.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;3：超时机制&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; 当我们coding的时候遇到了这种问题还是很纠结的，所以我们必须引入一种&amp;ldquo;超时机制&amp;rdquo;，如果在指定的时候内所有的参与者（task）都&lt;/p&gt;&lt;p&gt;没有到达屏障的话，我们就需要取消这些参与者的后续执行，幸好SignalAndWait给我们提供了超时的重载，为了能够取消后续执行，我们&lt;/p&gt;&lt;p&gt;还要采用CancellationToken机制。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;  1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Concurrent;&lt;br /&gt;&lt;span style="color: #008080;"&gt;  2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #008080;"&gt;  3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #008080;"&gt;  4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #008080;"&gt;  5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #008080;"&gt;  6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span style="color: #008080;"&gt;  7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;span style="color: #008080;"&gt;  8&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;  9&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 10&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 11&lt;/span&gt; &lt;span style="color: #008000;"&gt;//四&lt;/span&gt;&lt;span style="color: #008000;"&gt;个task执行&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 12&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Task[] tasks = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task[&lt;span style="color: #800080;"&gt;4&lt;/span&gt;];&lt;br /&gt;&lt;span style="color: #008080;"&gt; 13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 14&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Barrier barrier = &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 15&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 16&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 17&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 18&lt;/span&gt; CancellationTokenSource cts = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; CancellationTokenSource();&lt;br /&gt;&lt;span style="color: #008080;"&gt; 19&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 20&lt;/span&gt; CancellationToken ct = cts.Token;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 21&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 22&lt;/span&gt; barrier = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Barrier(tasks.Length, (i) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 23&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 24&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;**********************************************************&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 25&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n屏障中当前阶段编号:{0}\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, i.CurrentPhaseNumber);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 26&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;**********************************************************&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 27&lt;/span&gt; });&lt;br /&gt;&lt;span style="color: #008080;"&gt; 28&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 29&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; j = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; j &amp;lt; tasks.Length; j++)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 30&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 31&lt;/span&gt; tasks[j] = Task.Factory.StartNew((obj) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 32&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 33&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; single = Convert.ToInt32(obj);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 34&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 35&lt;/span&gt; LoadUser(single);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 36&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 37&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!barrier.SignalAndWait(&lt;span style="color: #800080;"&gt;2000&lt;/span&gt;))&lt;br /&gt;&lt;span style="color: #008080;"&gt; 38&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 39&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;抛出异常，取消后面加载的执行&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 40&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; OperationCanceledException(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;我是当前任务{0},我抛出异常了！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, single), ct);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 41&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 42&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 43&lt;/span&gt; LoadProduct(single);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 44&lt;/span&gt; barrier.SignalAndWait();&lt;br /&gt;&lt;span style="color: #008080;"&gt; 45&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 46&lt;/span&gt; LoadOrder(single);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 47&lt;/span&gt; barrier.SignalAndWait();&lt;br /&gt;&lt;span style="color: #008080;"&gt; 48&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 49&lt;/span&gt; }, j, ct);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 50&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 51&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 52&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;等待所有tasks 4s&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 53&lt;/span&gt; Task.WaitAll(tasks, &lt;span style="color: #800080;"&gt;4000&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 54&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 55&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 56&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 57&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; i = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;; i &amp;lt; tasks.Length; i++)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 58&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 59&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (tasks[i].Status == TaskStatus.Faulted)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 60&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 61&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;获取task中的异常&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 62&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; single &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; tasks[i].Exception.InnerExceptions)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 63&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 64&lt;/span&gt; Console.WriteLine(single.Message);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 65&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 66&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 67&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 68&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 69&lt;/span&gt; barrier.Dispose();&lt;br /&gt;&lt;span style="color: #008080;"&gt; 70&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 71&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt; (AggregateException e)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 72&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 73&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;我是总异常:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, e.Message);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 74&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 75&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 76&lt;/span&gt; Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt; 77&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 78&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 79&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; LoadUser(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; num)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 80&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 81&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n当前任务:{0}正在加载User部分数据！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, num);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 82&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 83&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (num == &lt;span style="color: #800080;"&gt;0&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 84&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 85&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;自旋转5s&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 86&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (!SpinWait.SpinUntil(() =&amp;gt; barrier.ParticipantsRemaining == &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #800080;"&gt;5000&lt;/span&gt;))&lt;br /&gt;&lt;span style="color: #008080;"&gt; 87&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 88&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 89&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 90&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前任务:{0}正在加载User数据完毕！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, num);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 91&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 92&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 93&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; LoadProduct(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; num)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 94&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 95&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前任务:{0}正在加载Product部分数据！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, num);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 96&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 97&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 98&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; LoadOrder(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; num)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 99&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;100&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前任务:{0}正在加载Order部分数据！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, num);&lt;br /&gt;&lt;span style="color: #008080;"&gt;101&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;102&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040721485684.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;二：spinLock（自旋锁）&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; 我们初识多线程或者多任务时，第一个想到的同步方法就是使用lock或者Monitor，然而在4.0 之后给我们提供了另一把武器spinLock，&lt;/p&gt;&lt;p&gt;如果你的任务持有锁的时间非常短，具体短到什么时候msdn也没有给我们具体的答案，但是有一点值得确定的时，如果持有锁的时候比较&lt;/p&gt;&lt;p&gt;短，那么它比那些重量级别的Monitor具有更小的性能开销，它的用法跟Monitor很相似，下面举个例子，Add2方法采用自旋锁。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Concurrent;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; SpinLock slock = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; SpinLock(&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; sum1 = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; sum2 = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; Task[] tasks = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task[&lt;span style="color: #800080;"&gt;100&lt;/span&gt;];&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; i = &lt;span style="color: #800080;"&gt;1&lt;/span&gt;; i &amp;lt;= &lt;span style="color: #800080;"&gt;100&lt;/span&gt;; i++)&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; tasks[i - &lt;span style="color: #800080;"&gt;1&lt;/span&gt;] = Task.Factory.StartNew((num) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; Add1((&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;)num);&lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; Add2((&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;)num);&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; }, i);&lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt; Task.WaitAll(tasks);&lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Add1数字总和:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, sum1);&lt;br /&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt; Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Add2数字总和:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, sum2);&lt;br /&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt; Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;无锁&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Add1(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; num)&lt;br /&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt; Thread.Sleep(&lt;span style="color: #800080;"&gt;100&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt; sum1 += num;&lt;br /&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;自旋锁&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Add2(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; num)&lt;br /&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; lockTaken = &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;54&lt;/span&gt; Thread.Sleep(&lt;span style="color: #800080;"&gt;100&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;55&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;56&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;57&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;58&lt;/span&gt; slock.Enter(&lt;span style="color: #0000ff;"&gt;ref&lt;/span&gt; lockTaken);&lt;br /&gt;&lt;span style="color: #008080;"&gt;59&lt;/span&gt; sum2 += num;&lt;br /&gt;&lt;span style="color: #008080;"&gt;60&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;61&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;finally&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;62&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;63&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt; (lockTaken)&lt;br /&gt;&lt;span style="color: #008080;"&gt;64&lt;/span&gt; slock.Exit(&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;65&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;66&lt;/span&gt; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;67&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040722503282.png" alt="" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangxincheng/aggbug/2437110.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangxincheng/archive/2012/04/07/2437110.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangxincheng/archive/2012/04/04/2431616.html</id><title type="text">8天玩转并行开发——第三天 plinq的使用</title><summary type="text">相信在.net平台下，我们都玩过linq，是的，linq让我们的程序简洁优美，简直玩的是爱不释手，但是传统的linq只是串行代码，在并行的年代如果linq不支持并行计算那该是多么遗憾的事情啊。 当然linq有很多种方式，比如linq to sql ,xml，object 等等，如果要将linq做成并行还是很简单的，这里我就举一个比较实际一点的例子，我们知道为了更快的响应用户操作，码农们想尽了各种办法，绞尽了脑汁，其中有一个办法就是将数据库数据预加载到内存中，然后通过各种数据结构的手段来加速CURD，是的，比如一个排序地球人只能做到N(lgN)，那么如果我还想再快一点的话该怎么办呢？那么现在..</summary><published>2012-04-03T17:05:00Z</published><updated>2012-04-03T17:05:00Z</updated><author><name>一线码农</name><uri>http://www.cnblogs.com/huangxincheng/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangxincheng/archive/2012/04/04/2431616.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangxincheng/archive/2012/04/04/2431616.html"/><content type="html">&lt;p&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;相信在.net平台下，我们都玩过linq，是的，linq让我们的程序简洁优美，简直玩的是爱不释手，但是传统的linq只是串行代码，在并行的&lt;/p&gt;&lt;p&gt;年代如果linq不支持并行计算那该是多么遗憾的事情啊。&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;当然linq有很多种方式，比如linq to sql ,xml，object 等等，如果要将linq做成并行还是很简单的，这里我就举一个比较实际一点的例子，&lt;/p&gt;&lt;p&gt;我们知道为了更快的响应用户操作，码农们想尽了各种办法，绞尽了脑汁，其中有一个办法就是将数据库数据预加载到内存中，然后通过各种&lt;/p&gt;&lt;p&gt;数据结构的手段来加速CURD，是的，比如一个排序地球人只能做到N(lgN)，那么如果我还想再快一点的话该怎么办呢？那么现在的并行就能发&lt;/p&gt;&lt;p&gt;挥巨大的优势，尤其是现在的服务器配置都是在8个硬件线程的情况下，你简直会狂笑好几天啊，好，不乱扯了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;1：AsParallel(并行化）&lt;/p&gt;&lt;p&gt;下面我们模拟给ConcurrentDictionary灌入1500w条记录，看看串行和并行效率上的差异，注意我的老爷机是2个硬件线程。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Concurrent;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; dic = LoadData();&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;         Stopwatch watch = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Stopwatch();&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;         watch.Start();&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;串行执行&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; query1 = (&lt;span style="color: #0000ff;"&gt;from&lt;/span&gt; n &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; dic.Values&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;                       &lt;span style="color: #0000ff;"&gt;where&lt;/span&gt; n.Age &amp;gt; &lt;span style="color: #800080;"&gt;20&lt;/span&gt; &amp;amp;&amp;amp; n.Age &amp;lt; &lt;span style="color: #800080;"&gt;25&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;                       &lt;span style="color: #0000ff;"&gt;select&lt;/span&gt; n).ToList();&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;         watch.Stop();&lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;串行计算耗费时间：{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, watch.ElapsedMilliseconds);&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;         watch.Restart();&lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; query2 = (&lt;span style="color: #0000ff;"&gt;from&lt;/span&gt; n &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; dic.Values.AsParallel()&lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;                       &lt;span style="color: #0000ff;"&gt;where&lt;/span&gt; n.Age &amp;gt; &lt;span style="color: #800080;"&gt;20&lt;/span&gt; &amp;amp;&amp;amp; n.Age &amp;lt; &lt;span style="color: #800080;"&gt;25&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt;                       &lt;span style="color: #0000ff;"&gt;select&lt;/span&gt; n).ToList();&lt;br /&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt;         watch.Stop();&lt;br /&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;并行计算耗费时间：{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, watch.ElapsedMilliseconds);&lt;br /&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt;         Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; ConcurrentDictionary&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;, Student&amp;gt; LoadData()&lt;br /&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt;         ConcurrentDictionary&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;, Student&amp;gt; dic = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ConcurrentDictionary&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;, Student&amp;gt;();&lt;br /&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;预加载1500w条记录&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt;         Parallel.For(&lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #800080;"&gt;15000000&lt;/span&gt;, (i) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; single = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Student()&lt;br /&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt;             {&lt;br /&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt;                 ID = i,&lt;br /&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt;                 Name = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;hxc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + i,&lt;br /&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt;                 Age = i % &lt;span style="color: #800080;"&gt;151&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #008080;"&gt;54&lt;/span&gt;                 CreateTime = DateTime.Now.AddSeconds(i)&lt;br /&gt;&lt;span style="color: #008080;"&gt;55&lt;/span&gt;             };&lt;br /&gt;&lt;span style="color: #008080;"&gt;56&lt;/span&gt;             dic.TryAdd(i, single);&lt;br /&gt;&lt;span style="color: #008080;"&gt;57&lt;/span&gt;         });&lt;br /&gt;&lt;span style="color: #008080;"&gt;58&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;59&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; dic;&lt;br /&gt;&lt;span style="color: #008080;"&gt;60&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;61&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;62&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Student&lt;br /&gt;&lt;span style="color: #008080;"&gt;63&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;64&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; ID { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;65&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;66&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; Name { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;67&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;68&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; Age { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;69&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;70&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; DateTime CreateTime { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;71&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;72&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040323024258.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;执行的结果还是比较震撼的，将近7倍，这是因为plinq的查询引擎会尽量利用cpu的所有硬件线程。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;2:常用方法的使用&lt;/p&gt;&lt;p&gt;&amp;lt;1&amp;gt; orderby&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 有时候我们并不是简单的select一下就ok了，可能需要将结果进行orderby操作，并行化引擎会把要遍历的数据分区，然后在每个区上进行&lt;/p&gt;&lt;p&gt;orderby操作，最后来一个总的orderby，这里很像算法中的&amp;ldquo;归并排序&amp;rdquo;。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040323570067.png" alt="" /&gt;&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Concurrent;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; dic = LoadData();&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; query1 = (&lt;span style="color: #0000ff;"&gt;from&lt;/span&gt; n &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; dic.Values.AsParallel()&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;                       &lt;span style="color: #0000ff;"&gt;where&lt;/span&gt; n.Age &amp;gt; &lt;span style="color: #800080;"&gt;20&lt;/span&gt; &amp;amp;&amp;amp; n.Age &amp;lt; &lt;span style="color: #800080;"&gt;25&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;                       &lt;span style="color: #0000ff;"&gt;select&lt;/span&gt; n).ToList();&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;默认的时间排序如下：&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;         query1.Take(&lt;span style="color: #800080;"&gt;10&lt;/span&gt;).ToList().ForEach((i) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;             Console.WriteLine(i.CreateTime);&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;         });&lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; query2 = (&lt;span style="color: #0000ff;"&gt;from&lt;/span&gt; n &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; dic.Values.AsParallel()&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;                       &lt;span style="color: #0000ff;"&gt;where&lt;/span&gt; n.Age &amp;gt; &lt;span style="color: #800080;"&gt;20&lt;/span&gt; &amp;amp;&amp;amp; n.Age &amp;lt; &lt;span style="color: #800080;"&gt;25&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;                       &lt;span style="color: #0000ff;"&gt;orderby&lt;/span&gt; n.CreateTime descending&lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;                       &lt;span style="color: #0000ff;"&gt;select&lt;/span&gt; n).ToList();&lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;排序后的时间排序如下：&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt;         query2.Take(&lt;span style="color: #800080;"&gt;10&lt;/span&gt;).ToList().ForEach((i) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt;             Console.WriteLine(i.CreateTime);&lt;br /&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt;         });&lt;br /&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt;         Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; ConcurrentDictionary&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;, Student&amp;gt; LoadData()&lt;br /&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt;         ConcurrentDictionary&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;, Student&amp;gt; dic = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ConcurrentDictionary&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;, Student&amp;gt;();&lt;br /&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;预加载1500w条记录&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt;         Parallel.For(&lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #800080;"&gt;15000000&lt;/span&gt;, (i) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; single = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Student()&lt;br /&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt;             {&lt;br /&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt;                 ID = i,&lt;br /&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt;                 Name = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;hxc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + i,&lt;br /&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt;                 Age = i % &lt;span style="color: #800080;"&gt;151&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt;                 CreateTime = DateTime.Now.AddSeconds(i)&lt;br /&gt;&lt;span style="color: #008080;"&gt;54&lt;/span&gt;             };&lt;br /&gt;&lt;span style="color: #008080;"&gt;55&lt;/span&gt;             dic.TryAdd(i, single);&lt;br /&gt;&lt;span style="color: #008080;"&gt;56&lt;/span&gt;         });&lt;br /&gt;&lt;span style="color: #008080;"&gt;57&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;58&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; dic;&lt;br /&gt;&lt;span style="color: #008080;"&gt;59&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;60&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;61&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Student&lt;br /&gt;&lt;span style="color: #008080;"&gt;62&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;63&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; ID { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;64&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;65&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; Name { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;66&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;67&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; Age { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;68&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;69&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; DateTime CreateTime { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;span style="color: #008080;"&gt;70&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;71&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040400024393.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;lt;2&amp;gt; sum(),average()等等这些聚合函数的效果跟orderby类型一样，都是实现了类型归并排序的效果，这里就不举例子了。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;3：指定并行度，这个我在前面文章也说过，为了不让并行计算占用全部的硬件线程，或许可能要留一个线程做其他事情。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; query2 = (&lt;span style="color: #0000ff;"&gt;from&lt;/span&gt; n &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; dic.Values.AsParallel()&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;                      &lt;span style="color: #ff0000;"&gt; .WithDegreeOfParallelism(Environment.ProcessorCount - 1)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;                       &lt;span style="color: #0000ff;"&gt;where&lt;/span&gt; n.Age &amp;gt; &lt;span style="color: #800080;"&gt;20&lt;/span&gt; &amp;amp;&amp;amp; n.Age &amp;lt; &lt;span style="color: #800080;"&gt;25&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;                       &lt;span style="color: #0000ff;"&gt;orderby&lt;/span&gt; n.CreateTime descending&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;                       &lt;span style="color: #0000ff;"&gt;select&lt;/span&gt; n).ToList();&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;4： 了解ParallelEnumerable类&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;首先这个类是Enumerable的并行版本，提供了很多用于查询实现的一组方法，截个图，大家看看是不是很熟悉，要记住，他们都是并行的。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040400273696.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;下面列举几个简单的例子。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;         ConcurrentBag&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&amp;gt; bag = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ConcurrentBag&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; list = ParallelEnumerable.Range(&lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #800080;"&gt;10000&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;         list.ForAll((i) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;             bag.Add(i);&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;         });&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;bag集合中元素个数有:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, bag.Count);&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;list集合中元素个数总和为:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, list.Sum());&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;list集合中元素最大值为:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, list.Max());&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;list集合中元素第一个元素为:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, list.FirstOrDefault());&lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;         Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040400334951.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;5： plinq实现MapReduce算法&lt;/p&gt;&lt;p&gt;&amp;nbsp; mapReduce是一个非常流行的编程模型，用于大规模数据集的并行计算，非常的牛X啊，记得mongodb中就用到了这个玩意。&lt;/p&gt;&lt;p&gt;map： &amp;nbsp;也就是&amp;ldquo;映射&amp;rdquo;操作，可以为每一个数据项建立一个键值对，映射完后会形成一个键值对的集合。&lt;/p&gt;&lt;p&gt;reduce：&amp;ldquo;化简&amp;rdquo;操作，我们对这些巨大的&amp;ldquo;键值对集合&amp;ldquo;进行分组，统计等等。&lt;/p&gt;&lt;p&gt;具体大家可以看看百科：&lt;a href="http://baike.baidu.com/view/2902.htm"&gt;http://baike.baidu.com/view/2902.htm&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;下面我举个例子，用Mapreduce来实现一个对age的分组统计。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Concurrent;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;    {&lt;br /&gt;        List&amp;lt;Student&amp;gt; list = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; List&amp;lt;Student&amp;gt;()&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Student(){ ID=&lt;span style="color: #800080;"&gt;1&lt;/span&gt;, Name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;jack&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, Age=&lt;span style="color: #800080;"&gt;20&lt;/span&gt;},&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Student(){ ID=&lt;span style="color: #800080;"&gt;1&lt;/span&gt;, Name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;mary&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, Age=&lt;span style="color: #800080;"&gt;25&lt;/span&gt;},&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Student(){ ID=&lt;span style="color: #800080;"&gt;1&lt;/span&gt;, Name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;joe&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, Age=&lt;span style="color: #800080;"&gt;29&lt;/span&gt;},&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Student(){ ID=&lt;span style="color: #800080;"&gt;1&lt;/span&gt;, Name=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Aaron&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, Age=&lt;span style="color: #800080;"&gt;25&lt;/span&gt;},&lt;br /&gt;        };&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;这里我们会对age建立一组键值对&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; map = list.AsParallel().ToLookup(i =&amp;gt; i.Age, count =&amp;gt; &lt;span style="color: #800080;"&gt;1&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;化简统计&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; reduce = &lt;span style="color: #0000ff;"&gt;from&lt;/span&gt; IGrouping&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&amp;gt; singleMap&lt;br /&gt;                     &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; map.AsParallel()&lt;br /&gt;                     &lt;span style="color: #0000ff;"&gt;select&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;br /&gt;                     {&lt;br /&gt;                         Age = singleMap.Key,&lt;br /&gt;                         Count = singleMap.Count()&lt;br /&gt;                     };&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt;最后遍历&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        reduce.ForAll(i =&amp;gt;&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前Age={0}的人数有:{1}人&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, i.Age, i.Count);&lt;br /&gt;        });&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Student&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; ID { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; Name { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; Age { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; DateTime CreateTime { &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt;; }&lt;br /&gt;    }&lt;br /&gt;}&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040400580975.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangxincheng/aggbug/2431616.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangxincheng/archive/2012/04/04/2431616.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangxincheng/archive/2012/04/03/2430638.html</id><title type="text">8天玩转并行开发——第二天 Task的使用</title><summary type="text">在我们了解Task之前，如果我们要使用多核的功能可能就会自己来开线程，然而这种线程模型在.net 4.0之后被一种称为基于“任务的编程模型”所冲击，因为task会比thread具有更小的性能开销，不过大家肯定会有疑惑，任务和线程到底有什么区别？1：任务是架构在线程之上的，也就是说任务最终还是要抛给线程去执行。2：任务跟线程不是一对一的关系，比如开10个任务并不是说会开10个线程，这一点任务有点类似线程池，但是任务相比线程池有很小 的开销和精确的控制。一：Task1. 最简单的使用 开启task有两种方式:&lt;1&gt; 实例化Task1 //第一种方式开启2 var ...</summary><published>2012-04-02T17:47:00Z</published><updated>2012-04-02T17:47:00Z</updated><author><name>一线码农</name><uri>http://www.cnblogs.com/huangxincheng/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangxincheng/archive/2012/04/03/2430638.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangxincheng/archive/2012/04/03/2430638.html"/><content type="html">&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;在我们了解Task之前，如果我们要使用多核的功能可能就会自己来开线程，然而这种线程模型在.net 4.0之后被一种称为基于&lt;/p&gt;&lt;p&gt;&amp;ldquo;任务的编程模型&amp;rdquo;所冲击，因为task会比thread具有更小的性能开销，不过大家肯定会有疑惑，任务和线程到底有什么区别？&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;1：任务是架构在线程之上的，也就是说任务最终还是要抛给线程去执行。&lt;/p&gt;&lt;p&gt;2：任务跟线程不是一对一的关系，比如开10个任务并不是说会开10个线程，这一点任务有点类似线程池，但是任务相比线程池有很小&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 的开销和精确的控制。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;一：Task&lt;/p&gt;&lt;p&gt;1. 最简单的使用&lt;/p&gt;&lt;p&gt;&amp;nbsp; 开启task有两种方式:&lt;/p&gt;&lt;p&gt;&amp;lt;1&amp;gt; 实例化Task&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;    &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;第一种方式开启&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; task1 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task(() =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;             Run1();&lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;         });&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;lt;2&amp;gt;从工厂中创建&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;   &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; task2 = Task.Factory.StartNew(() =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;             {&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;                 Run2();&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt;             });&lt;/div&gt;&lt;p&gt;&lt;br /&gt;是的，同样两种方法都可以创建，我们肯定会想两者是不是多多少少有点区别呢？好的，下面我们举个例子看分晓。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;第一种方式开启&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; task1 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task(() =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;             Run1();&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;         });&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;第二种方式开启&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; task2 = Task.Factory.StartNew(() =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;             {&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;                 Run2();&lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;             });&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;调用start之前****************************\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;调用start之前的&amp;ldquo;任务状态&amp;rdquo;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;task1的状态:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, task1.Status);&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;task2的状态:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, task2.Status);&lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;         task1.Start();&lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n调用start之后****************************&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;调用start之前的&amp;ldquo;任务状态&amp;rdquo;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\ntask1的状态:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, task1.Status);&lt;br /&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;task2的状态:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, task2.Status);&lt;br /&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;主线程等待任务执行完&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt;         Task.WaitAll(task1, task2);&lt;br /&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n任务执行完后的状态****************************&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;调用start之前的&amp;ldquo;任务状态&amp;rdquo;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\ntask1的状态:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, task1.Status);&lt;br /&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;task2的状态:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, task2.Status);&lt;br /&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt;         Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run1()&lt;br /&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;54&lt;/span&gt;         Thread.Sleep(&lt;span style="color: #800080;"&gt;1000&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;55&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n我是任务1&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;56&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;57&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;58&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run2()&lt;br /&gt;&lt;span style="color: #008080;"&gt;59&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;60&lt;/span&gt;         Thread.Sleep(&lt;span style="color: #800080;"&gt;2000&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;61&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;我是任务2&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;62&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;63&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040300150851.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;①：从图中可以看出两种task实例的简略生命周期。&lt;/p&gt;&lt;p&gt;Created：表示默认初始化任务，但是我们发现&amp;ldquo;工厂创建的&amp;rdquo;实例直接跳过。&lt;/p&gt;&lt;p&gt;WaitingToRun: 这种状态表示等待任务调度器分配线程给任务执行。&lt;/p&gt;&lt;p&gt;RanToCompletion：任务执行完毕。&lt;/p&gt;&lt;p&gt;②：我们发现task的使用跟Thread很相似，就连waitAll的方法使用也一样，刚才也说了，任务是架构在线程之上，那么我们用VS里面的&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;ldquo;并行任务&amp;rdquo;看一看，快捷键Ctrl+D，K，或者找到&amp;ldquo;调试"-&amp;gt;"窗口&amp;ldquo;-&amp;gt;"并行任务&amp;ldquo;，我们在WaitAll方法处插入一个断点，最终我们发现&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 任务确实托管给了线程。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040300325418.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;2. 取消任务&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;我们知道task是并行计算的，比如说主线程在某个时刻由于某种原因要取消某个task的执行，我们能做到吗? 当然我们可以做到。&lt;/p&gt;&lt;p&gt;在4.0中给我们提供一个&amp;ldquo;取消标记&amp;rdquo;叫做CancellationTokenSource.Token，在创建task的时候传入此参数，就可以将主线程和任务相&lt;/p&gt;&lt;p&gt;关联，然后在任务中设置&amp;ldquo;取消信号&amp;ldquo;叫做ThrowIfCancellationRequested来等待主线程使用Cancel来通知，一旦cancel被调用。task将会&lt;/p&gt;&lt;p&gt;抛出OperationCanceledException来中断此任务的执行，最后将当前task的Status的IsCanceled属性设为true。看起来是不是很抽象，&lt;/p&gt;&lt;p&gt;没关系，上代码说话。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; cts = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; CancellationTokenSource();&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; ct = cts.Token;&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;         Task task1 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task(() =&amp;gt; { Run1(ct); }, ct);&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;         Task task2 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Task(Run2);&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;             task1.Start();&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;             task2.Start();&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;             Thread.Sleep(&lt;span style="color: #800080;"&gt;1000&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;             cts.Cancel();&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;             Task.WaitAll(task1, task2);&lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;catch&lt;/span&gt; (AggregateException ex)&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt; (&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; e &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; ex.InnerExceptions)&lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;             {&lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;                 Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\nhi,我是OperationCanceledException：{0}\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, e.Message);&lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;             }&lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;task1是否取消&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;task1是不是被取消了？ {0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, task1.IsCanceled);&lt;br /&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;task2是不是被取消了？ {0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, task2.IsCanceled);&lt;br /&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt;         Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run1(CancellationToken ct)&lt;br /&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt;         ct.ThrowIfCancellationRequested();&lt;br /&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;我是任务1&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt;         Thread.Sleep(&lt;span style="color: #800080;"&gt;2000&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt;         ct.ThrowIfCancellationRequested();&lt;br /&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;我是任务1的第二部分信息&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;54&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;55&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run2()&lt;br /&gt;&lt;span style="color: #008080;"&gt;56&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;57&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;我是任务2&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;58&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;59&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;从图中可以看出&lt;/p&gt;&lt;p&gt;①：Run1中的Console.WriteLine("我是任务1的第二部分信息"); 没有被执行。&lt;/p&gt;&lt;p&gt;②：Console.WriteLine("task1是不是被取消了？ {0}", task1.IsCanceled); 状态为True。&lt;/p&gt;&lt;p&gt;也就告诉我们Run1中途被主线程中断执行，我们coding的代码起到效果了。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040313300239.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;3. 获取任务的返回值&lt;/p&gt;&lt;p&gt;&amp;nbsp; 我们以前写线程的时候注册的方法一般都是void类型，如果主线程要从工作线程中获取数据一般采用的手段是&amp;ldquo;委托+事件&amp;rdquo;的模式，然而&lt;/p&gt;&lt;p&gt;在Task中有两种方式可以解决。&lt;/p&gt;&lt;p&gt;&amp;lt;1&amp;gt; &amp;nbsp;现在我们的实例化是采用Task&amp;lt;TResult&amp;gt;的形式，其中TResult就是当前task执行后返回的结果，下面举得例子是t2任务获取&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;t1的执行结果。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;执行task1&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; t1 = Task.Factory.StartNew&amp;lt;List&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt;&amp;gt;(() =&amp;gt; { &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; Run1(); });&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;         t1.Wait();&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; t2 = Task.Factory.StartNew(() =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;t1集合中返回的个数：&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;.Join(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;,&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, t1.Result));&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;         });&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;         Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; List&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt; Run1()&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt; { &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;1&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;4&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;8&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; };&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040301080775.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&amp;lt;2&amp;gt;采用ContinueWith方法，很有意思，现在我们将上面的方法改造一下。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;执行task1&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; t1 = Task.Factory.StartNew&amp;lt;List&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt;&amp;gt;(() =&amp;gt; { &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; Run1(); });&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; t2 = t1.ContinueWith((i) =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;t1集合中返回的个数：&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;.Join(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;,&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, i.Result));&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;         });&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;         Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; List&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt; Run1()&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&amp;gt; { &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;1&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;4&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;8&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; };&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040301080775.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;4：ContinueWith结合WaitAll来玩一把&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; 当这两者结合起来，我们就可以玩一些复杂一点的东西，比如说现在有7个任务，其中t1需要串行，t2-t3可以并行，t4需要串行，t5-t6并行，&lt;/p&gt;&lt;p&gt;t7串行。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040301213042.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;好了，我们上一下代码说话，下面代码没有实际意思，纯属演示。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;using&lt;/span&gt; System.Collections.Concurrent;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;         ConcurrentStack&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&amp;gt; stack = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ConcurrentStack&amp;lt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;t1先串行&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; t1 = Task.Factory.StartNew(() =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;             stack.Push(&lt;span style="color: #800080;"&gt;1&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;             stack.Push(&lt;span style="color: #800080;"&gt;2&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;         });&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;t2,t3并行执行&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; t2 = t1.ContinueWith(t =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; result;&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;             stack.TryPop(&lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; result);&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;         });&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;t2,t3并行执行&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; t3 = t1.ContinueWith(t =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; result;&lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt;             stack.TryPop(&lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; result);&lt;br /&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt;         });&lt;br /&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;等待t2和t3执行完&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt;         Task.WaitAll(t2, t3);&lt;br /&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;t4串行执行&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; t4 = Task.Factory.StartNew(() =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt;             stack.Push(&lt;span style="color: #800080;"&gt;1&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt;             stack.Push(&lt;span style="color: #800080;"&gt;2&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt;         });&lt;br /&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;t5,t6并行执行&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; t5 = t4.ContinueWith(t =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; result;&lt;br /&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt;             stack.TryPop(&lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; result);&lt;br /&gt;&lt;span style="color: #008080;"&gt;54&lt;/span&gt;         });&lt;br /&gt;&lt;span style="color: #008080;"&gt;55&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;56&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;t5,t6并行执行&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;57&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; t6 = t4.ContinueWith(t =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;58&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;59&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; result;&lt;br /&gt;&lt;span style="color: #008080;"&gt;60&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;61&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;只弹出，不移除&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;62&lt;/span&gt;             stack.TryPeek(&lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; result);&lt;br /&gt;&lt;span style="color: #008080;"&gt;63&lt;/span&gt;         });&lt;br /&gt;&lt;span style="color: #008080;"&gt;64&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;65&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;临界区：等待t5，t6执行完&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;66&lt;/span&gt;         Task.WaitAll(t5, t6);&lt;br /&gt;&lt;span style="color: #008080;"&gt;67&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;68&lt;/span&gt;         &lt;span style="color: #008000;"&gt;//t7&lt;/span&gt;&lt;span style="color: #008000;"&gt;串行执行&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;69&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; t7 = Task.Factory.StartNew(() =&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;70&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;71&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前集合元素个数：&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; + stack.Count);&lt;br /&gt;&lt;span style="color: #008080;"&gt;72&lt;/span&gt;         });&lt;br /&gt;&lt;span style="color: #008080;"&gt;73&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;74&lt;/span&gt;         Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;75&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;76&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040301462249.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangxincheng/aggbug/2430638.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangxincheng/archive/2012/04/03/2430638.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangxincheng/archive/2012/04/02/2429543.html</id><title type="text">8天玩转并行开发——第一天 Parallel的使用</title><summary type="text">随着多核时代的到来，并行开发越来越展示出它的强大威力，像我们这样的码农再也不用过多的关注底层线程的实现和手工控制，要了解并行开发，需要先了解下两个概念：“硬件线程”和“软件线程”。1. 硬件线程 相信大家手头的电脑都是双核以上的，像我这样古董的电脑都是双核的，这样的双核叫做物理内核。硬件线程又叫做逻辑内核，我们可以在”任务管理器“中查看”性能“标签页，如下图，我们知道有2个硬件线程。一般情况下，一个物理内核对应一个逻辑内核，比如我这里的2对2。当然如果你的cpu采用的是超线程技术，那么可能就会有4个物理内核对应8个硬件线程，现在有很多服务器都有8个硬件线程，上午在公司的服务器上截了个图...</summary><published>2012-04-01T18:10:00Z</published><updated>2012-04-01T18:10:00Z</updated><author><name>一线码农</name><uri>http://www.cnblogs.com/huangxincheng/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangxincheng/archive/2012/04/02/2429543.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangxincheng/archive/2012/04/02/2429543.html"/><content type="html">&lt;div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 随着多核时代的到来，并行开发越来越展示出它的强大威力，像我们这样的码农再也不用过多的关注底层线程的实现和手工控制，&lt;/p&gt;&lt;p&gt;要了解并行开发，需要先了解下两个概念：&amp;ldquo;硬件线程&amp;rdquo;和&amp;ldquo;软件线程&amp;rdquo;。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;1. 硬件线程&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; 相信大家手头的电脑都是双核以上的，像我这样古董的电脑都是双核的，这样的双核叫做物理内核。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040200362240.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;硬件线程又叫做逻辑内核，我们可以在&amp;rdquo;任务管理器&amp;ldquo;中查看&amp;rdquo;性能&amp;ldquo;标签页，如下图，我们知道有2个硬件线程。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040200350037.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;一般情况下，一个物理内核对应一个逻辑内核，比如我这里的2对2。当然如果你的cpu采用的是超线程技术，那么可能就会有4个物理内核对应&lt;/p&gt;&lt;p&gt;8个硬件线程，现在有很多服务器都有8个硬件线程，上午在公司的服务器上截了个图。&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040200373411.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;我们要知道并行开发要做的事情就是将任务分摊给这些硬件线程去并行执行来达到负载和加速。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;2. 软件线程&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; 相信这个大家最熟悉了，我们知道传统的代码都是串行的，就一个主线程，当我们为了实现加速而开了很多工作线程，这些工作线程&lt;/p&gt;&lt;p&gt;也就是软件线程。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;好，我们知道了基本概念就ok了，在.net 4.0中，微软给我们提供了一个新的命名空间：System.Threading.Tasks。这里面有很多好玩&lt;/p&gt;&lt;p&gt;的东西，作为第一篇就介绍下最基础，最简单的Parallel的使用。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040200391151.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;一：&amp;nbsp;Parallel的使用&lt;/p&gt;&lt;p&gt;在Parallel下面有三个常用的方法invoke,for和forEach。&lt;/p&gt;&lt;p&gt;1: &amp;nbsp;Parallel.Invoke&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; 这是最简单，最简洁的将串行的代码并行化。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span data-mce-=""&gt; 1&lt;/span&gt; &lt;span data-mce-=""&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span data-mce-=""&gt; 2&lt;/span&gt; {&lt;br /&gt;&lt;span data-mce-=""&gt; 3&lt;/span&gt;     &lt;span data-mce-=""&gt;static&lt;/span&gt; &lt;span data-mce-=""&gt;void&lt;/span&gt; Main(&lt;span data-mce-=""&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span data-mce-=""&gt; 4&lt;/span&gt;     {&lt;br /&gt;&lt;span data-mce-=""&gt; 5&lt;/span&gt;         &lt;span data-mce-=""&gt;var&lt;/span&gt; watch = Stopwatch.StartNew();&lt;br /&gt;&lt;span data-mce-=""&gt; 6&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt; 7&lt;/span&gt;         watch.Start();&lt;br /&gt;&lt;span data-mce-=""&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt; 9&lt;/span&gt;         Run1();&lt;br /&gt;&lt;span data-mce-=""&gt;10&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;11&lt;/span&gt;         Run2();&lt;br /&gt;&lt;span data-mce-=""&gt;12&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;13&lt;/span&gt;         Console.WriteLine(&lt;span data-mce-=""&gt;"&lt;/span&gt;&lt;span data-mce-=""&gt;我是串行开发，总共耗时:{0}\n&lt;/span&gt;&lt;span data-mce-=""&gt;"&lt;/span&gt;, watch.ElapsedMilliseconds);&lt;br /&gt;&lt;span data-mce-=""&gt;14&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;15&lt;/span&gt;         watch.Restart();&lt;br /&gt;&lt;span data-mce-=""&gt;16&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;17&lt;/span&gt;         Parallel.Invoke(Run1, Run2);&lt;br /&gt;&lt;span data-mce-=""&gt;18&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;19&lt;/span&gt;         watch.Stop();&lt;br /&gt;&lt;span data-mce-=""&gt;20&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;21&lt;/span&gt;         Console.WriteLine(&lt;span data-mce-=""&gt;"&lt;/span&gt;&lt;span data-mce-=""&gt;我是并行开发，总共耗时:{0}&lt;/span&gt;&lt;span data-mce-=""&gt;"&lt;/span&gt;, watch.ElapsedMilliseconds);&lt;br /&gt;&lt;span data-mce-=""&gt;22&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;23&lt;/span&gt;         Console.Read();&lt;br /&gt;&lt;span data-mce-=""&gt;24&lt;/span&gt;     }&lt;br /&gt;&lt;span data-mce-=""&gt;25&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;26&lt;/span&gt;     &lt;span data-mce-=""&gt;static&lt;/span&gt; &lt;span data-mce-=""&gt;void&lt;/span&gt; Run1()&lt;br /&gt;&lt;span data-mce-=""&gt;27&lt;/span&gt;     {&lt;br /&gt;&lt;span data-mce-=""&gt;28&lt;/span&gt;         Console.WriteLine(&lt;span data-mce-=""&gt;"&lt;/span&gt;&lt;span data-mce-=""&gt;我是任务一,我跑了3s&lt;/span&gt;&lt;span data-mce-=""&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span data-mce-=""&gt;29&lt;/span&gt;         Thread.Sleep(&lt;span data-mce-=""&gt;3000&lt;/span&gt;);&lt;br /&gt;&lt;span data-mce-=""&gt;30&lt;/span&gt;     }&lt;br /&gt;&lt;span data-mce-=""&gt;31&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;32&lt;/span&gt;     &lt;span data-mce-=""&gt;static&lt;/span&gt; &lt;span data-mce-=""&gt;void&lt;/span&gt; Run2()&lt;br /&gt;&lt;span data-mce-=""&gt;33&lt;/span&gt;     {&lt;br /&gt;&lt;span data-mce-=""&gt;34&lt;/span&gt;         Console.WriteLine(&lt;span data-mce-=""&gt;"&lt;/span&gt;&lt;span data-mce-=""&gt;我是任务二，我跑了5s&lt;/span&gt;&lt;span data-mce-=""&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span data-mce-=""&gt;35&lt;/span&gt;         Thread.Sleep(&lt;span data-mce-=""&gt;5000&lt;/span&gt;);&lt;br /&gt;&lt;span data-mce-=""&gt;36&lt;/span&gt;     }&lt;br /&gt;&lt;span data-mce-=""&gt;37&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040200471421.png" alt="" /&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;&amp;nbsp;&lt;/p&gt;&lt;p&gt;2：Parallel.for&lt;/p&gt;&lt;p&gt;&amp;nbsp;我们知道串行代码中也有一个for，但是那个for并没有用到多核，而Paraller.for它会在底层根据硬件线程的运行状况来充分的使用所有的可&lt;/p&gt;&lt;p&gt;利用的硬件线程，注意这里的Parallel.for的步行是1。&lt;/p&gt;&lt;p&gt;这里我们来演示一下，向一个线程安全的集合插入数据，当然这个集合采用原子性来实现线程同步，比那些重量级的锁机制更加的节省消耗。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span data-mce-=""&gt; 1&lt;/span&gt;  &lt;span data-mce-=""&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span data-mce-=""&gt; 2&lt;/span&gt;     {&lt;br /&gt;&lt;span data-mce-=""&gt; 3&lt;/span&gt;         &lt;span data-mce-=""&gt;static&lt;/span&gt; &lt;span data-mce-=""&gt;void&lt;/span&gt; Main(&lt;span data-mce-=""&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span data-mce-=""&gt; 4&lt;/span&gt;         {&lt;br /&gt;&lt;span data-mce-=""&gt; 5&lt;/span&gt;             &lt;span data-mce-=""&gt;for&lt;/span&gt; (&lt;span data-mce-=""&gt;int&lt;/span&gt; j = &lt;span data-mce-=""&gt;1&lt;/span&gt;; j &amp;lt; &lt;span data-mce-=""&gt;4&lt;/span&gt;; j++)&lt;br /&gt;&lt;span data-mce-=""&gt; 6&lt;/span&gt;             {&lt;br /&gt;&lt;span data-mce-=""&gt; 7&lt;/span&gt;                 Console.WriteLine(&lt;span data-mce-=""&gt;"&lt;/span&gt;&lt;span data-mce-=""&gt;\n第{0}次比较&lt;/span&gt;&lt;span data-mce-=""&gt;"&lt;/span&gt;, j);&lt;br /&gt;&lt;span data-mce-=""&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt; 9&lt;/span&gt;                 ConcurrentBag&amp;lt;&lt;span data-mce-=""&gt;int&lt;/span&gt;&amp;gt; bag = &lt;span data-mce-=""&gt;new&lt;/span&gt; ConcurrentBag&amp;lt;&lt;span data-mce-=""&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;span data-mce-=""&gt;10&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;11&lt;/span&gt;                 &lt;span data-mce-=""&gt;var&lt;/span&gt; watch = Stopwatch.StartNew();&lt;br /&gt;&lt;span data-mce-=""&gt;12&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;13&lt;/span&gt;                 watch.Start();&lt;br /&gt;&lt;span data-mce-=""&gt;14&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;15&lt;/span&gt;                 &lt;span data-mce-=""&gt;for&lt;/span&gt; (&lt;span data-mce-=""&gt;int&lt;/span&gt; i = &lt;span data-mce-=""&gt;0&lt;/span&gt;; i &amp;lt; &lt;span data-mce-=""&gt;20000000&lt;/span&gt;; i++)&lt;br /&gt;&lt;span data-mce-=""&gt;16&lt;/span&gt;                 {&lt;br /&gt;&lt;span data-mce-=""&gt;17&lt;/span&gt;                     bag.Add(i);&lt;br /&gt;&lt;span data-mce-=""&gt;18&lt;/span&gt;                 }&lt;br /&gt;&lt;span data-mce-=""&gt;19&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;20&lt;/span&gt;                 Console.WriteLine(&lt;span data-mce-=""&gt;"&lt;/span&gt;&lt;span data-mce-=""&gt;串行计算：集合有:{0},总共耗时：{1}&lt;/span&gt;&lt;span data-mce-=""&gt;"&lt;/span&gt;, bag.Count, watch.ElapsedMilliseconds);&lt;br /&gt;&lt;span data-mce-=""&gt;21&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;22&lt;/span&gt;                 GC.Collect();&lt;br /&gt;&lt;span data-mce-=""&gt;23&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;24&lt;/span&gt;                 bag = &lt;span data-mce-=""&gt;new&lt;/span&gt; ConcurrentBag&amp;lt;&lt;span data-mce-=""&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;span data-mce-=""&gt;25&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;26&lt;/span&gt;                 watch = Stopwatch.StartNew();&lt;br /&gt;&lt;span data-mce-=""&gt;27&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;28&lt;/span&gt;                 watch.Start();&lt;br /&gt;&lt;span data-mce-=""&gt;29&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;30&lt;/span&gt;                 Parallel.For(&lt;span data-mce-=""&gt;0&lt;/span&gt;, &lt;span data-mce-=""&gt;20000000&lt;/span&gt;, i =&amp;gt;&lt;br /&gt;&lt;span data-mce-=""&gt;31&lt;/span&gt;                 {&lt;br /&gt;&lt;span data-mce-=""&gt;32&lt;/span&gt;                     bag.Add(i);&lt;br /&gt;&lt;span data-mce-=""&gt;33&lt;/span&gt;                 });&lt;br /&gt;&lt;span data-mce-=""&gt;34&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;35&lt;/span&gt;                 Console.WriteLine(&lt;span data-mce-=""&gt;"&lt;/span&gt;&lt;span data-mce-=""&gt;并行计算：集合有:{0},总共耗时：{1}&lt;/span&gt;&lt;span data-mce-=""&gt;"&lt;/span&gt;, bag.Count, watch.ElapsedMilliseconds);&lt;br /&gt;&lt;span data-mce-=""&gt;36&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;37&lt;/span&gt;                 GC.Collect();&lt;br /&gt;&lt;span data-mce-=""&gt;38&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;39&lt;/span&gt;             }&lt;br /&gt;&lt;span data-mce-=""&gt;40&lt;/span&gt;         }&lt;br /&gt;&lt;span data-mce-=""&gt;41&lt;/span&gt;     }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040201065859.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;可以看的出，加速的效果还是比较明显的。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;3：Parallel.forEach&lt;br /&gt;&amp;nbsp; &amp;nbsp; forEach的独到之处就是可以将数据进行分区，每一个小区内实现串行计算，分区采用Partitioner.Create实现。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; &lt;span data-mce-=""&gt;class&lt;/span&gt; Program&lt;br /&gt;    {&lt;br /&gt;        &lt;span data-mce-=""&gt;static&lt;/span&gt; &lt;span data-mce-=""&gt;void&lt;/span&gt; Main(&lt;span data-mce-=""&gt;string&lt;/span&gt;[] args)&lt;br /&gt;        {&lt;br /&gt;            &lt;span data-mce-=""&gt;for&lt;/span&gt; (&lt;span data-mce-=""&gt;int&lt;/span&gt; j = &lt;span data-mce-=""&gt;1&lt;/span&gt;; j &amp;lt; &lt;span data-mce-=""&gt;4&lt;/span&gt;; j++)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine(&lt;span data-mce-=""&gt;"&lt;/span&gt;&lt;span data-mce-=""&gt;\n第{0}次比较&lt;/span&gt;&lt;span data-mce-=""&gt;"&lt;/span&gt;, j);&lt;br /&gt;&lt;br /&gt;                ConcurrentBag&amp;lt;&lt;span data-mce-=""&gt;int&lt;/span&gt;&amp;gt; bag = &lt;span data-mce-=""&gt;new&lt;/span&gt; ConcurrentBag&amp;lt;&lt;span data-mce-=""&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;br /&gt;                &lt;span data-mce-=""&gt;var&lt;/span&gt; watch = Stopwatch.StartNew();&lt;br /&gt;&lt;br /&gt;                watch.Start();&lt;br /&gt;&lt;br /&gt;                &lt;span data-mce-=""&gt;for&lt;/span&gt; (&lt;span data-mce-=""&gt;int&lt;/span&gt; i = &lt;span data-mce-=""&gt;0&lt;/span&gt;; i &amp;lt; &lt;span data-mce-=""&gt;3000000&lt;/span&gt;; i++)&lt;br /&gt;                {&lt;br /&gt;                    bag.Add(i);&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                Console.WriteLine(&lt;span data-mce-=""&gt;"&lt;/span&gt;&lt;span data-mce-=""&gt;串行计算：集合有:{0},总共耗时：{1}&lt;/span&gt;&lt;span data-mce-=""&gt;"&lt;/span&gt;, bag.Count, watch.ElapsedMilliseconds);&lt;br /&gt;&lt;br /&gt;                GC.Collect();&lt;br /&gt;&lt;br /&gt;                bag = &lt;span data-mce-=""&gt;new&lt;/span&gt; ConcurrentBag&amp;lt;&lt;span data-mce-=""&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;br /&gt;                watch = Stopwatch.StartNew();&lt;br /&gt;&lt;br /&gt;                watch.Start();&lt;br /&gt;&lt;br /&gt;              &lt;span&gt;  Parallel.ForEach(Partitioner.Create(0, 3000000), i =&amp;gt;&lt;/span&gt;&lt;br /&gt;                {&lt;br /&gt;                    &lt;span data-mce-=""&gt;for&lt;/span&gt; (&lt;span data-mce-=""&gt;int&lt;/span&gt; m = i.Item1; m &amp;lt; i.Item2; m++)&lt;br /&gt;                    {&lt;br /&gt;                        bag.Add(m);&lt;br /&gt;                    }&lt;br /&gt;                });&lt;br /&gt;&lt;br /&gt;                Console.WriteLine(&lt;span data-mce-=""&gt;"&lt;/span&gt;&lt;span data-mce-=""&gt;并行计算：集合有:{0},总共耗时：{1}&lt;/span&gt;&lt;span data-mce-=""&gt;"&lt;/span&gt;, bag.Count, watch.ElapsedMilliseconds);&lt;br /&gt;&lt;br /&gt;                GC.Collect();&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040201154091.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;这里还是要说一下：Partitioner.Create(0, 3000000)。&lt;/p&gt;&lt;p&gt;第一：我们要分区的范围是0-3000000。&lt;/p&gt;&lt;p&gt;第二：我们肯定想知道系统给我们分了几个区? 很遗憾，这是系统内部协调的，无权告诉我们，当然系统也不反对我们自己指定分区个数，&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 这里可以使用Partitioner.Create的第六个重载，比如这样：Partitioner.Create(0, 3000000, Environment.ProcessorCount)，&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 因为&amp;nbsp;Environment.ProcessorCount能够获取到当前的硬件线程数，所以这里也就开了2个区。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;下面分享下并行计算中我们可能有的疑惑？&lt;/p&gt;&lt;p&gt;&amp;lt;1&amp;gt; 如何中途退出并行循环？&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 是的，在串行代码中我们break一下就搞定了，但是并行就不是这么简单了，不过没关系，在并行循环的委托参数中提供了一个&lt;/p&gt;&lt;p&gt;ParallelLoopState，该实例提供了Break和Stop方法来帮我们实现。&lt;/p&gt;&lt;p&gt;Break: 当然这个是通知并行计算尽快的退出循环，比如并行计算正在迭代100，那么break后程序还会迭代所有小于100的。&lt;/p&gt;&lt;p&gt;Stop：这个就不一样了，比如正在迭代100突然遇到stop，那它啥也不管了，直接退出。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;下面举个例子，当迭代到1000的时候退出循环&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span data-mce-=""&gt; 1&lt;/span&gt;   &lt;span data-mce-=""&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span data-mce-=""&gt; 2&lt;/span&gt;     {&lt;br /&gt;&lt;span data-mce-=""&gt; 3&lt;/span&gt;         &lt;span data-mce-=""&gt;static&lt;/span&gt; &lt;span data-mce-=""&gt;void&lt;/span&gt; Main(&lt;span data-mce-=""&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span data-mce-=""&gt; 4&lt;/span&gt;         {&lt;br /&gt;&lt;span data-mce-=""&gt; 5&lt;/span&gt;             &lt;span data-mce-=""&gt;var&lt;/span&gt; watch = Stopwatch.StartNew();&lt;br /&gt;&lt;span data-mce-=""&gt; 6&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt; 7&lt;/span&gt;             watch.Start();&lt;br /&gt;&lt;span data-mce-=""&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt; 9&lt;/span&gt;             ConcurrentBag&amp;lt;&lt;span data-mce-=""&gt;int&lt;/span&gt;&amp;gt; bag = &lt;span data-mce-=""&gt;new&lt;/span&gt; ConcurrentBag&amp;lt;&lt;span data-mce-=""&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;span data-mce-=""&gt;10&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;11&lt;/span&gt;             Parallel.For(&lt;span data-mce-=""&gt;0&lt;/span&gt;, &lt;span data-mce-=""&gt;20000000&lt;/span&gt;, (i, state) =&amp;gt;&lt;br /&gt;&lt;span data-mce-=""&gt;12&lt;/span&gt;                   {&lt;br /&gt;&lt;span data-mce-=""&gt;13&lt;/span&gt;                       &lt;span data-mce-=""&gt;if&lt;/span&gt; (bag.Count == &lt;span data-mce-=""&gt;1000&lt;/span&gt;)&lt;br /&gt;&lt;span data-mce-=""&gt;14&lt;/span&gt;                       {&lt;br /&gt;&lt;span data-mce-=""&gt;15&lt;/span&gt;                           state.Break();&lt;br /&gt;&lt;span data-mce-=""&gt;16&lt;/span&gt;                           &lt;span data-mce-=""&gt;return&lt;/span&gt;;&lt;br /&gt;&lt;span data-mce-=""&gt;17&lt;/span&gt;                       }&lt;br /&gt;&lt;span data-mce-=""&gt;18&lt;/span&gt;                       bag.Add(i);&lt;br /&gt;&lt;span data-mce-=""&gt;19&lt;/span&gt;                   });&lt;br /&gt;&lt;span data-mce-=""&gt;20&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;21&lt;/span&gt;             Console.WriteLine(&lt;span data-mce-=""&gt;"&lt;/span&gt;&lt;span data-mce-=""&gt;当前集合有{0}个元素。&lt;/span&gt;&lt;span data-mce-=""&gt;"&lt;/span&gt;, bag.Count);&lt;br /&gt;&lt;span data-mce-=""&gt;22&lt;/span&gt; &lt;br /&gt;&lt;span data-mce-=""&gt;23&lt;/span&gt;         }&lt;br /&gt;&lt;span data-mce-=""&gt;24&lt;/span&gt;     }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040201391475.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;lt;2&amp;gt; 并行计算中抛出异常怎么处理？&lt;/p&gt;&lt;p&gt;&amp;nbsp;首先任务是并行计算的，处理过程中可能会产生n多的异常，那么如何来获取到这些异常呢？普通的Exception并不能获取到异常，然而为并行诞生的AggregateExcepation就可以获取到一组异常。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span data-mce-=""&gt;class&lt;/span&gt; Program&lt;br /&gt;{&lt;br /&gt;    &lt;span data-mce-=""&gt;static&lt;/span&gt; &lt;span data-mce-=""&gt;void&lt;/span&gt; Main(&lt;span data-mce-=""&gt;string&lt;/span&gt;[] args)&lt;br /&gt;    {&lt;br /&gt;        &lt;span data-mce-=""&gt;try&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            Parallel.Invoke(Run1, Run2);&lt;br /&gt;        }&lt;br /&gt;        &lt;span data-mce-=""&gt;catch&lt;/span&gt; (AggregateException ex)&lt;br /&gt;        {&lt;br /&gt;            &lt;span data-mce-=""&gt;foreach&lt;/span&gt; (&lt;span data-mce-=""&gt;var&lt;/span&gt; single &lt;span data-mce-=""&gt;in&lt;/span&gt; ex.InnerExceptions)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine(single.Message);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        Console.Read();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span data-mce-=""&gt;static&lt;/span&gt; &lt;span data-mce-=""&gt;void&lt;/span&gt; Run1()&lt;br /&gt;    {&lt;br /&gt;        Thread.Sleep(&lt;span data-mce-=""&gt;3000&lt;/span&gt;);&lt;br /&gt;        &lt;span data-mce-=""&gt;throw&lt;/span&gt; &lt;span data-mce-=""&gt;new&lt;/span&gt; Exception(&lt;span data-mce-=""&gt;"&lt;/span&gt;&lt;span data-mce-=""&gt;我是任务1抛出的异常&lt;/span&gt;&lt;span data-mce-=""&gt;"&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span data-mce-=""&gt;static&lt;/span&gt; &lt;span data-mce-=""&gt;void&lt;/span&gt; Run2()&lt;br /&gt;    {&lt;br /&gt;        Thread.Sleep(&lt;span data-mce-=""&gt;5000&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;        &lt;span data-mce-=""&gt;throw&lt;/span&gt; &lt;span data-mce-=""&gt;new&lt;/span&gt; Exception(&lt;span data-mce-=""&gt;"&lt;/span&gt;&lt;span data-mce-=""&gt;我是任务2抛出的异常&lt;/span&gt;&lt;span data-mce-=""&gt;"&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;}&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012040201482731.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;lt;3&amp;gt; 并行计算中我可以留一个硬件线程出来吗？&lt;/p&gt;&lt;p&gt;&amp;nbsp; 默认的情况下，底层机制会尽可能多的使用硬件线程，然而我们使用手动指定的好处是我们可以在2，4，8个硬件线程的情况下来进行测量加速比。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; &lt;span data-mce-=""&gt;class&lt;/span&gt; Program&lt;br /&gt;    {&lt;br /&gt;        &lt;span data-mce-=""&gt;static&lt;/span&gt; &lt;span data-mce-=""&gt;void&lt;/span&gt; Main(&lt;span data-mce-=""&gt;string&lt;/span&gt;[] args)&lt;br /&gt;        {&lt;br /&gt;            &lt;span data-mce-=""&gt;var&lt;/span&gt; bag = &lt;span data-mce-=""&gt;new&lt;/span&gt; ConcurrentBag&amp;lt;&lt;span data-mce-=""&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;br /&gt;            ParallelOptions options = &lt;span data-mce-=""&gt;new&lt;/span&gt; ParallelOptions();&lt;br /&gt;&lt;br /&gt;            &lt;span data-mce-=""&gt;//&lt;/span&gt;&lt;span data-mce-=""&gt;指定使用的硬件线程数为1&lt;/span&gt;&lt;span data-mce-=""&gt;&lt;br /&gt;&lt;/span&gt;           &lt;span&gt; options.MaxDegreeOfParallelism = 1;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;            Parallel.For(&lt;span data-mce-=""&gt;0&lt;/span&gt;, &lt;span data-mce-=""&gt;300000&lt;/span&gt;, options, i =&amp;gt;&lt;br /&gt;            {&lt;br /&gt;                bag.Add(i);&lt;br /&gt;            });&lt;br /&gt;&lt;br /&gt;            Console.WriteLine(&lt;span data-mce-=""&gt;"&lt;/span&gt;&lt;span data-mce-=""&gt;并行计算：集合有:{0}&lt;/span&gt;&lt;span data-mce-=""&gt;"&lt;/span&gt;, bag.Count);&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;    }&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/huangxincheng/aggbug/2429543.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangxincheng/archive/2012/04/02/2429543.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangxincheng/archive/2012/03/18/2405039.html</id><title type="text">5天不再惧怕多线程——第五天 线程池</title><summary type="text">说到多线程，不可不说线程池，C#中关于池的概念很多，今天来整理下ThreadPool的使用。 是的，如果你很懒，如果你的执行任务比较短，如果你不想对线程做更精细的控制，那么把这些繁琐的东西丢给线程池吧。一：ThreadPool好了，下面看看TheadPool下有哪些常用的方法。1：GetMaxThreads,GetMinThreads 首先我们肯定好奇线程池到底给我们如何控制线程数，下面就具体的看一看。 1 class Program 2 { 3 static void Main(string[] args) 4 { 5 in...</summary><published>2012-03-18T12:30:00Z</published><updated>2012-03-18T12:30:00Z</updated><author><name>一线码农</name><uri>http://www.cnblogs.com/huangxincheng/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangxincheng/archive/2012/03/18/2405039.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangxincheng/archive/2012/03/18/2405039.html"/><content type="html">&lt;p&gt;&amp;nbsp; &amp;nbsp; 说到多线程，不可不说线程池，C#中关于池的概念很多，今天来整理下ThreadPool的使用。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;是的，如果你很懒，如果你的执行任务比较短，如果你不想对线程做更精细的控制，那么把这些繁琐的东西丢给线程池吧。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;一：ThreadPool&lt;/p&gt;&lt;p&gt;&amp;nbsp;好了，下面看看TheadPool下有哪些常用的方法。&lt;/p&gt;&lt;p&gt;1：GetMaxThreads,GetMinThreads&lt;/p&gt;&lt;p&gt;&amp;nbsp; 首先我们肯定好奇线程池到底给我们如何控制线程数，下面就具体的看一看。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; workerThreads;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; completePortsThreads;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;             ThreadPool.GetMaxThreads(&lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; workerThreads, &lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; completePortsThreads);&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;线程池中最大的线程数{0},线程池中异步IO线程的最大数目{1}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, workerThreads, completePortsThreads);&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;             ThreadPool.GetMinThreads(&lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; workerThreads, &lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; completePortsThreads);&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;线程池中最小的线程数{0},线程池中异步IO线程的最小数目{1}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, workerThreads, completePortsThreads);&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;     }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012031819105837.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;有的同学可能就要问，我可以将1023设置为10230吗？那么就会有10230个线程帮我做事多好啊，其实不然。&lt;/p&gt;&lt;p&gt;①：我先前的文章也说过，线程很多的话，线程调度就越频繁，可能就会出现某个任务执行的时间比线程调度花费的时间短很多的尴尬局面。&lt;/p&gt;&lt;p&gt;②：我们要知道一个线程默认占用1M的堆栈空间，如果10230个线程将会占用差不多10G的内存空间，我想普通的电脑立马罢工。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;2：SetMaxTheads,SetMinThreads&lt;/p&gt;&lt;p&gt;当然，默认的线程设置只是一个参考，如果我们处于性能和实际情况确实需要修改也没关系，framework也给我们提供了现成的方法。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; workerThreads;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;             &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; completePortsThreads;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt;            &lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;             ThreadPool.SetMaxThreads(&lt;span style="color: #800080;"&gt;100&lt;/span&gt;, &lt;span style="color: #800080;"&gt;50&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;             ThreadPool.SetMinThreads(&lt;span style="color: #800080;"&gt;20&lt;/span&gt;, &lt;span style="color: #800080;"&gt;10&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;             ThreadPool.GetMaxThreads(&lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; workerThreads, &lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; completePortsThreads);&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;线程池中最大的线程数{0},线程池中异步IO线程的最大数目{1}\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, workerThreads, completePortsThreads);&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;             ThreadPool.GetMinThreads(&lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; workerThreads, &lt;span style="color: #0000ff;"&gt;out&lt;/span&gt; completePortsThreads);&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;线程池中最小的线程数{0},线程池中异步IO线程的最小数目{1}\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, workerThreads, completePortsThreads);&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;     }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012031819254688.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;3：&amp;nbsp;QueueUserWorkItem&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; 需要容纳任务并执行的方法来了，该方法有一个WaitCallBack的委托，我们只需要把将要执行的任务丢给委托，CLR将会在线程池中调派空闲的&lt;/p&gt;&lt;p&gt;线程执行。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt; ConsoleApplication3&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;        {&lt;br /&gt;            ThreadPool.QueueUserWorkItem(Run1);&lt;br /&gt;&lt;br /&gt;            Console.Read();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run1(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; obj)&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;我是线程{0}，我是线程池中的线程吗？ \n回答：{1}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, Thread.CurrentThread.ManagedThreadId,&lt;br /&gt;                                                                           Thread.CurrentThread.IsThreadPoolThread);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012031819383916.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;可能我们也需要像普通的Thread一样带一些参数到工作线程中,QueueUserWorkItem的第二个重载版本解决了我们的问题。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt;    &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;             ThreadPool.QueueUserWorkItem(Run1, &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;我是主线程&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;             Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run1(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; obj)&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;             Console.WriteLine(obj);&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;     }&lt;/div&gt;&lt;p&gt;&lt;br /&gt;4：RegisterWaitForSingleObject&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;我们知道，如果我们把要执行的任务丢给线程池后，相当于把自己的命运寄托在别人的手上。&lt;/p&gt;&lt;p&gt;①：我们再也不能控制线程的优先级了。&lt;/p&gt;&lt;p&gt;②：丢给线程池后，我们再也不能将要执行的任务取消了。&lt;/p&gt;&lt;p&gt;是的，给别人就要遵守别人的游戏规则，不过RegisterWaitForSingleObject提供了一些简单的线程间交互，因为该方法的第一个参数是&lt;/p&gt;&lt;p&gt;WaitHandle，在VS对象浏览器中，我们发现EventWaitHandle继承了WaitHandle，而ManualResetEvent和AutoResetEvent都继承于&lt;/p&gt;&lt;p&gt;EventWaitHandle，也就是说我们可以在RegisterWaitForSingleObject溶于信号量的概念。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;             AutoResetEvent ar = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; AutoResetEvent(&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;             ThreadPool.RegisterWaitForSingleObject(ar, Run1, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, Timeout.Infinite, &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;时间:{0} 工作线程请注意，您需要等待5s才能执行。\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, DateTime.Now);&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;5s&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;             Thread.Sleep(&lt;span style="color: #800080;"&gt;5000&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;             ar.Set();&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;时间:{0} 工作线程已执行。\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, DateTime.Now);&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;             Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run1(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; obj, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; sign)&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前时间:{0}  我是线程{1}\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, DateTime.Now, Thread.CurrentThread.ManagedThreadId);&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;     }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012031820073511.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;我们知道在Threading下面有一个Timer计时器，当定期触发任务的时候都是由线程池提供并给予执行，那么这里我们溶于信号量的概念以后同样&lt;/p&gt;&lt;p&gt;可以实现计时器的功能。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;             AutoResetEvent ar = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; AutoResetEvent(&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;参数2000：其实就是WaitOne(2000)，采取超时机制&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt;             ThreadPool.RegisterWaitForSingleObject(ar, Run1, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, &lt;span style="color: #800080;"&gt;2000&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt;             Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run1(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; obj, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; sign)&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前时间:{0}  我是线程{1}\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, DateTime.Now, Thread.CurrentThread.ManagedThreadId);&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012031820132452.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;有时候，跑着跑着我们需要在某个时刻停止它，没关系，RegisterWaitForSingleObject返回一个RegisteredWaitHandle类，那么我们就通过&lt;/p&gt;&lt;p&gt;RegisteredWaitHandle来动态的控制，比如说停止计数器的运行。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt;   &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;             RegisteredWaitHandle handle = &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;             AutoResetEvent ar = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; AutoResetEvent(&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;             handle = ThreadPool.RegisterWaitForSingleObject(ar, Run1, &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;, &lt;span style="color: #800080;"&gt;2000&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;             &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;10s后停止&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;             Thread.Sleep(&lt;span style="color: #800080;"&gt;10000&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;             handle.Unregister(ar);&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;小子，主线程要干掉你了。&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;             Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run1(&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt; obj, &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; sign)&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前时间:{0}  我是线程{1}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, DateTime.Now, Thread.CurrentThread.ManagedThreadId);&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;     }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012031820193833.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangxincheng/aggbug/2405039.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangxincheng/archive/2012/03/18/2405039.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/huangxincheng/archive/2012/03/17/2404181.html</id><title type="text">5天不再惧怕多线程——第四天 信号量</title><summary type="text">今天整理“信号量”的相关知识，其实想想也蛮有趣的，锁，互斥，信号量都可以实现线程同步，在framework里面主要有三种。&lt;1&gt;：ManualResetEvent&lt;2&gt;：AutoResetEvent&lt;3&gt;:Semaphore好，下面就具体看看这些玩意的使用。一：ManualResetEvent 该对象有两种信号量状态True和False，好奇的我们肯定想知道True和False有什么区别，稍后的例子见分晓，有三个方法值得学习一下。1：WaitOne 该方法用于阻塞线程，默认是无限期的阻塞，有时我们并不想这样，而是采取超时阻塞的方法，如果超时就放弃阻塞，这样也</summary><published>2012-03-17T15:33:00Z</published><updated>2012-03-17T15:33:00Z</updated><author><name>一线码农</name><uri>http://www.cnblogs.com/huangxincheng/</uri></author><link rel="alternate" href="http://www.cnblogs.com/huangxincheng/archive/2012/03/17/2404181.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/huangxincheng/archive/2012/03/17/2404181.html"/><content type="html">&lt;p&gt;&amp;nbsp; &amp;nbsp; 今天整理&amp;ldquo;信号量&amp;rdquo;的相关知识，其实想想也蛮有趣的，锁，互斥，信号量都可以实现线程同步，在framework里面主要有三种。&lt;/p&gt;&lt;p&gt;&amp;lt;1&amp;gt;：ManualResetEvent&lt;/p&gt;&lt;p&gt;&amp;lt;2&amp;gt;：AutoResetEvent&lt;/p&gt;&lt;p&gt;&amp;lt;3&amp;gt;:&amp;nbsp;Semaphore&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;好，下面就具体看看这些玩意的使用。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;一：ManualResetEvent&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 该对象有两种信号量状态True和False，好奇的我们肯定想知道True和False有什么区别，稍后的例子见分晓，有三个方法值得学习一下。&lt;/p&gt;&lt;p&gt;1：WaitOne&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;该方法用于阻塞线程，默认是无限期的阻塞，有时我们并不想这样，而是采取超时阻塞的方法，如果超时就放弃阻塞，这样也就避免了无限期&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;等待的尴尬。&lt;/p&gt;&lt;p&gt;2：Set&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;手动修改信号量为True，也就是恢复线程执行。&lt;/p&gt;&lt;p&gt;3:ReSet&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;手动修改信号量为False，暂停线程执行。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;好了，下面举个例子说明一下。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;lt;1&amp;gt; &amp;nbsp;信号量初始为False，WaitOne采用无限期阻塞，可以发现线程间可以进行交互。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Example&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main()&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;         Thread t = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Thread(Run);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;         t.Name = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Jack&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前时间:{0}  {1} {1},我是主线程,收到请回答。&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, DateTime.Now, t.Name);&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;         t.Start();&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;         Thread.Sleep(&lt;span style="color: #800080;"&gt;5000&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;         &lt;span style="color: #ff0000;"&gt;mr.Set();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;         Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; ManualResetEvent mr = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ManualResetEvent(&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run()&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;        &lt;span style="color: #ff0000;"&gt; mr.WaitOne();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n当前时间:{0}  主线程，主线程,{1}已收到！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, DateTime.Now, Thread.CurrentThread.Name);&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012031721571141.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;lt;2&amp;gt;&amp;nbsp;信号量初始为True，WaitOne采用无限期阻塞，实验发现WaitOne其实并没有被阻塞。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; ManualResetEvent mr = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ManualResetEvent(&lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;);&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012031722092264.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;lt;3&amp;gt;信号量初始为False，WaitOne采用超时2s，虽然主线程要等5s才能进行Set操作，但是WaitOne已经等不及提前执行了。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Example&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main()&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;         Thread t = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Thread(Run);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;         t.Name = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Jack&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前时间:{0}  {1} {1},我是主线程,收到请回答。&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, DateTime.Now, t.Name);&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;         t.Start();&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt;         Thread.Sleep(&lt;span style="color: #800080;"&gt;5000&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;         mr.Set();&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;         Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; ManualResetEvent mr = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; ManualResetEvent(&lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run()&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;        &lt;span style="color: #ff0000;"&gt; mr.WaitOne(2000);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n当前时间:{0}  主线程，主线程,{1}已收到！&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, DateTime.Now, Thread.CurrentThread.Name);&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012031722125511.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;二：AutoResetEvent&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 在VS对象浏览器中，我们发现AutoResetEvent和ManualResetEvent都是继承于EventWaitHandle，所以基本功能是一样的，不过值得注意&lt;/p&gt;&lt;p&gt;的一个区别是WaitOne会改变信号量的值，比如说初始信号量为True，如果WaitOne超时信号量将自动变为False，而ManualResetEvent则不会。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Example&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main()&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;         Thread t = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Thread(Run);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt;         t.Name = &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Jack&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;;&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;         t.Start();&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;         Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; AutoResetEvent ar = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; AutoResetEvent(&lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run()&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;var&lt;/span&gt; state = ar.WaitOne(&lt;span style="color: #800080;"&gt;1000&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;我当前的信号量状态:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, state);&lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt;         state = ar.WaitOne(&lt;span style="color: #800080;"&gt;1000&lt;/span&gt;, &lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;         Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;我恨你，不理我，您现在的状态是:{0}&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, state);&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012031722281285.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;三：Semaphore&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;这玩意是.net 4.0新增的，用于控制线程的访问数量，默认的构造函数为initialCount和maximumCount，表示默认设置的信号量个数和&lt;/p&gt;&lt;p&gt;最大信号量个数，其实说到底，里面是采用计数器来来分配信号量，当你WaitOne的时候，信号量自减，当Release的时候，信号量自增，然而&lt;/p&gt;&lt;p&gt;当信号量为0的时候，后续的线程就不能拿到WaitOne了，所以必须等待先前的线程通过Release来释放。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;好了，下面还是举例子来说明一下：&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;lt;1&amp;gt; initialCount=1,maximunCount=10,WaitOne采用无限期等待。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt; ConsoleApplication3&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt;             Thread t1 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Thread(Run1);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;             t1.Start();&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;             Thread t2 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Thread(Run2);&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;             t2.Start();&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;             Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;         &lt;span style="color: #ff0000;"&gt;static Semaphore sem = new Semaphore(1, 10);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run1()&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;            &lt;span style="color: #ff0000;"&gt; sem.WaitOne();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;大家好，我是Run1&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run2()&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;             &lt;span style="color: #ff0000;"&gt;sem.WaitOne();&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;大家好，我是Run2&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012031722461770.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;我们悲剧的发现t2线程不能执行，我们知道WaitOne相当于自减信号量，然而默认的信号量个数为1，所以t2想执行必须等待t1通过Release来释放。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run1()&lt;br /&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt;             sem.WaitOne();&lt;br /&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;大家好，我是Run1&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;7&lt;/span&gt;             sem.Release();&lt;br /&gt;&lt;span style="color: #008080;"&gt;8&lt;/span&gt;         }&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;可能有的同学要问，我不是设置了maximunCount=10吗？为什么没有起到作用？是的，默认情况下是没有起到作用，必须要我们手动干预一下，&lt;/p&gt;&lt;p&gt;我们知道调用Release方法相当于自增一个信号量，然而Release有一个重载，可以指定自增到maximunCount个信号量，这里我就在主线程上&lt;/p&gt;&lt;p&gt;Release(10),看看效果。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt; ConsoleApplication3&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt;             Thread t1 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Thread(Run1);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;             t1.Start();&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;             Thread t2 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Thread(Run2);&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;             t2.Start();&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;             Thread.Sleep(&lt;span style="color: #800080;"&gt;1000&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt;             &lt;span style="color: #ff0000;"&gt;sem.Release(10);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt;             Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; Semaphore sem = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Semaphore(&lt;span style="color: #800080;"&gt;1&lt;/span&gt;, &lt;span style="color: #800080;"&gt;10&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run1()&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt;             sem.WaitOne();&lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;大家好，我是Run1&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run2()&lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;             sem.WaitOne();&lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;大家好，我是Run2&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;);&lt;br /&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012031723024161.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&amp;lt;2&amp;gt; Semaphore命名，升级进程交互。&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 在VS对象浏览器中发现Semaphore是继承字WaitHandle，而WaitHandle封装了win32的一些同步机制，所以当我们给Semaphore命名的时候&lt;/p&gt;&lt;p&gt;就会在系统中可见，下面举个例子，把下面的代码copy一份，运行两个程序。&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt; ConsoleApplication3&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt;     &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt;     {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt;             Thread t1 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Thread(Run1);&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt;             t1.Start();&lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt;             Thread t2 = &lt;span style="color: #0000ff;"&gt;new&lt;/span&gt; Thread(Run2);&lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt;             t2.Start();&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt;             Console.Read();&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt;         &lt;span style="color: #ff0000;"&gt;static Semaphore sem = new Semaphore(3, 10, "cnblogs");&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run1()&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt;             sem.WaitOne();&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前时间:{0} 大家好，我是Run1&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, DateTime.Now);&lt;br /&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt;         &lt;span style="color: #0000ff;"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Run2()&lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt;         {&lt;br /&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt;             sem.WaitOne();&lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt;             Console.WriteLine(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;当前时间:{0} 大家好，我是Run2&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;, DateTime.Now);&lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt;         }&lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt;     }&lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; }&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/214741/2012031723204922.png" alt="" /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;是的，我设置了信号量是3个，所以只能有三个线程持有WaitOne，后续的线程只能苦苦的等待。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/huangxincheng/aggbug/2404181.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/huangxincheng/archive/2012/03/17/2404181.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
