使用多线程获取网页内容的代码如下:
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密集型工作,采用异步机制。