什么是APM
.net 1.0时期就提出的一种异步模式,并且基于IAsyncResult接口实现BeginXXX和EndXXX类似的方法。
.net中有很多类实现了该模式(比如HttpWebRequest),同时我们也可以自定义类来实现APM模式(继承IAsyncResult接口并且实现BeginXXX和EndXXX方法),下面的Demo就以HttpWebRequest类来实现APM模式的异步。
Demo
下面分别使用同步和异步APM模式来实现,读取一个网页内容,并且将内容展示到界面上。
1,同步
就是平常我们写代码的方式,代码如下。
1 /// <summary> 2 /// 同步 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void button1_Click(object sender, EventArgs e) 7 { 8 //先清空上一次查询结果 9 this.richTextBox1.Text = ""; 10 11 var url = this.textBox1.Text.Trim(); 12 var request = HttpWebRequest.Create(url); 13 var response = request.GetResponse(); 14 var stream = response.GetResponseStream(); 15 using (StreamReader reader= new StreamReader(stream)) 16 { 17 var content = reader.ReadToEnd(); 18 this.richTextBox1.Text = content; 19 } 20 }
2,异步(APM)
主要是通过BeginGetResponse和EndGetResponse来调用的。
1 /// <summary> 2 /// 异步 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void button2_Click(object sender, EventArgs e) 7 { 8 //先清空上一次查询结果 9 this.richTextBox1.Text = ""; 10 11 var url = this.textBox1.Text.Trim(); 12 var request = HttpWebRequest.Create(url); 13 request.BeginGetResponse(AsyncCallbackImpl, request);//BeginGetResponse,发起异步请求 14 } 15 16 /// <summary> 17 /// 回调 18 /// </summary> 19 /// <param name="ar"></param> 20 public void AsyncCallbackImpl(IAsyncResult ar) 21 { 22 HttpWebRequest request = ar.AsyncState as HttpWebRequest; 23 var response = request.EndGetResponse(ar);//EndGetResponse,异步请求完成 24 var stream = response.GetResponseStream(); 25 StringBuilder sb = new StringBuilder(); 26 sb.AppendLine("当前线程Id:" + Thread.CurrentThread.ManagedThreadId); 27 using (StreamReader reader = new StreamReader(stream)) 28 { 29 var content = reader.ReadLine(); 30 sb.AppendLine(content); 31 this.richTextBox1.Text = sb.ToString(); 32 } 33 }
同步的方式,代码是顺序执行的,并且发送请求的时候界面会阻塞。但是异步模式界面不会阻塞,主线程会立即返回,等到异步请求完成的时候再从线程池中取一个线程处理。