佳佳的博客
Menu
首页
使用APM(Asynchronous Programming Model)异步委托编程模型
Posted by
佳佳
on 2016-02-18
IT
异步编写模型是一种模式,该模式允许用更少的线程去做更多的操作,.NET Framework很多类也实现了该模式,同时我们也可以自定义类来实现该模式,(也就是在自定义的类中实现返回类型为IAsyncResult接口的BeginXXX方法和EndXXX方法),另外委托类型也定义了`BeginInvoke`和`EndInvoke`方法,并且我们使用`WSDL.exe`和`SvcUtil.exe`工具来生成Web服务的代理类型时,也会生成使用了APM的`BeginXxx`和`EndXxx`方法。 本示例是一个控制台程序,异步读取网页并输出到控制台。用到了下面几个异步方法: 1. `HttpWebRequest.BeginGetResponse` 2. `HttpWebRequest.EndGetResponse` 3. `Stream.BeginRead` 4. `Stream.EndRead` 看一下`HttpWebRequest.BeginGetResponse`的方法定义: ```cs public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state); ``` 返回值为`IAsyncResult`类型,第一个参数为`AsyncCallback`类型。 `AsyncCallback`是个代理,其定义如下(一个参数类型为`IAsyncResult`的代理): ```cs public delegate void AsyncCallback(IAsyncResult ar); ``` `IAsyncResult`接口的定义如下: ```cs public interface IAsyncResult { object AsyncState { get; } WaitHandle AsyncWaitHandle { get; } bool CompletedSynchronously { get; } bool IsCompleted { get; } } ``` 其中`AsyncState`中的值即是`BeginGetResponse`方法调用时传进来的`state`参数。 #### 示例代码 - `Program.cs` ```cs using System; using System.IO; using System.Net; using System.Text; namespace APMSample { class Program { static void Main(string args) { DownloadFileAsync("http://baidu.com/"); Console.WriteLine("Start DownLoad the Page."); Console.ReadLine(); } private static void DownloadFileAsync(string url) { try { HttpWebRequest myHttpWebRequest = WebRequest.Create(url) as HttpWebRequest; RequestState requestState = new RequestState(); requestState.Request = myHttpWebRequest; myHttpWebRequest.BeginGetResponse(ResponseCallback, requestState); } catch (Exception e) { Console.WriteLine("Error Message is {0}", e.Message); } } private static void ResponseCallback(IAsyncResult ar) { RequestState myRequestState = ar.AsyncState as RequestState; HttpWebRequest myHttpWebRequest = myRequestState.Request; myRequestState.Response = myHttpWebRequest.EndGetResponse(ar) as HttpWebResponse; Stream responseStream = myRequestState.Response.GetResponseStream(); myRequestState.ResponseStream = responseStream; IAsyncResult asynchronousRead = responseStream.BeginRead(myRequestState.BufferRead, 0, myRequestState.BufferRead.Length, ReadCallback, myRequestState); } private static void ReadCallback(IAsyncResult ar) { try { RequestState myRequestState = ar.AsyncState as RequestState; Stream responseStream = myRequestState.ResponseStream; int readSize = responseStream.EndRead(ar); if (readSize > 0) { Console.Write(Encoding.UTF8.GetString(myRequestState.BufferRead)); myRequestState.BufferRead = new byte[myRequestState.BufferRead.Length]; responseStream.BeginRead(myRequestState.BufferRead, 0, myRequestState.BufferRead.Length, ReadCallback, myRequestState); } else { Console.WriteLine(); Console.WriteLine("DownLoad Completely."); myRequestState.Response.Close(); } } catch (Exception e) { Console.WriteLine("Error Message is:{0}", e.Message); } } } } ``` - `RequestState.cs` ```cs using System.IO; using System.Net; namespace APMSample { public class RequestState { public HttpWebRequest Request { get; set; } public HttpWebResponse Response { get; set; } public Stream ResponseStream { get; set; } public byte BufferRead { get; set; } = new byte[1000]; } } ``` #### 输出结果 ```html Start DownLoad the Page. <html> <meta http-equiv="refresh" content="0;url=http://www.baidu.com/"> </html> DownLoad Completely. ``` #### 参考文章 - [[你必须知道的异步编程]——异步编程模型(APM)](http://blog.csdn.net/xinke453/article/details/37810823)
版权声明:原创文章,未经允许不得转载。
https://www.liujiajia.me/2016/2/18/使用apmasynchronous-programming-model异步委托编程模型
“Buy me a nongfu spring”
« 使用Delegate实现APM(异步委托编程模型)
使用mysqldump备份MySQL数据 »
昵称
*
电子邮箱
*
回复内容
*
(回复审核后才会显示)
提交
目录
AUTHOR
刘佳佳
江苏 - 苏州
软件工程师
梦嘉集团