代码改变世界

区分异步和多线程

2015-08-10 17:41  佳佳的博客  阅读(166)  评论(0编辑  收藏  举报

使用多线程获取网页内容的代码如下:

 1 using System;
 2 using System.IO;
 3 using System.Net;
 4 using System.Threading;
 5 using System.Windows.Forms;
 6 
 7 namespace CS_71
 8 {
 9     public partial class Form1 : Form
10     {
11         // This delegate enables asynchronous calls for setting
12         // the text property on a TextBox control.
13         delegate void SetTextCallback(string text);
14 
15         public Form1()
16         {
17             InitializeComponent();
18         }
19 
20         private void btnGetPageThread_Click(object sender, EventArgs e)
21         {
22             Thread t = new Thread(new ThreadStart(() =>
23             {
24                 var request = HttpWebRequest.Create("http://www.cnblogs.com/ryukaka");
25                 var response = request.GetResponse();
26                 var stream = response.GetResponseStream();
27 
28                 using (StreamReader reader = new StreamReader(stream))
29                 {
30                     var content = reader.ReadToEnd();
31                     //MessageBox.Show(content);
32                     //txtPage.Text = content;
33                     SetText(content);
34                 }
35             }));
36             t.Start();
37         }
38 
39         private void SetText(string text)
40         {
41             // InvokeRequired required compares the thread ID of the
42             // calling thread to the thread ID of the creating thread.
43             // If these threads are different, it returns true.
44             if (txtPage.InvokeRequired)
45             {
46                 SetTextCallback d = new SetTextCallback(SetText);
47                 Invoke(d, new object[] { text });
48             }
49             else
50             {
51                 txtPage.Text = text;
52             }
53         }
54     }
55 }

为了获取网页,CLR新起了一个工作线程,然后在读取网页的整个过程中,该工作线程始终被阻滞,直到获取网页完毕为止。

在整个过程中工作线程被占用着,这意味着系统的资源始终被消耗着、等待着。

 

修改为如下异步模型:

 1 using System;
 2 using System.IO;
 3 using System.Net;
 4 using System.Threading;
 5 using System.Windows.Forms;
 6 
 7 namespace CS_71
 8 {
 9     public partial class Form1 : Form
10     {
11         // This delegate enables asynchronous calls for setting
12         // the text property on a TextBox control.
13         delegate void SetTextCallback(string text);
14 
15         public Form1()
16         {
17             InitializeComponent();
18         }
19 
20         private void btnGetPageAsync_Click(object sender, EventArgs e)
21         {
22             var request = HttpWebRequest.Create("http://www.cnblogs.com/ryukaka");
23             request.BeginGetRequestStream(this.AsyncCallbackImpl, request);
24         }
25 
26         public void AsyncCallbackImpl(IAsyncResult ar)
27         {
28             WebRequest request = ar.AsyncState as WebRequest;
29             var response = request.EndGetResponse(ar);
30             var stream = response.GetResponseStream();
31             using (StreamReader reader = new StreamReader(stream))
32             {
33                 var content = reader.ReadToEnd();
34                 txtPage.Text = content;
35             }
36         }
37     }
38 }

异步模式使用线程池进行管理。新起异步操作后,CLR会将工作丢给线程池中的某个工作线程来完成。

当I/O操作开始的时候,异步会将工作线程还给线程池,这时候就相当于获取网页的这个过程不会再占用CPU的资源了。

 

应用场景:

计算密集型工作,采用多线程。

IO密集型工作,采用异步机制。