《CLR via C#》读书笔记-异步编程(二)
2016-11-24 22:40
417 查看
在《CLR via C#》的27.2小节中使用了命名管道的内容,上一篇是一个使用命名管道的例子,在《CLR via C#》中同样有一个命名管道的例子(使用异步),具体内容如下:
服务器端的代码:
通过上面的这个例子,可以看到APM(Asynchronous Programming Model)的编写模式,在方法的内部,以Endxxx为开始,以BeginXXX为结束,在两者之间是相关的内容处理。
参数说明
对BeginXXX中方法的参数说明:方法的前三个参数是正常的,第四个参数是AsyncCallback,该委托的定义如下:
可以将
IAsyncResult的AsyncState就可以用于数据传输,由beginxxx传入到endxxx中。下面是客户端的代码
如何使用服务器端和客户端的程序
使用服务器端的代码如下:
使用客户端的代码如下
以上的代码均来自《CLR via C#》的27.2小节。代码很简单,抄录很麻烦。肩膀都酸了。
小节
APM与其他正常的代码没有任何的差别,不管是异常处理还是其他方面,基本上一模一样。只有一个例外,就是在使用beginxxx和endxxx时略有差别。与多线程相比较,基本上没有什么太大的花样。
在27.2的开头,反而是讲了APM的关键信息
1、所有派生自system.io.stream并与硬件通信的类(包括filestream和networkstream)都提供APM
2、system.net.dns类提供了几个方法
3、system.net.sockets.socket类中提供符合APM编程方式的方法
另外,所有委托都定义了一个begininvoke方法。
总的来说,APM编码方式是一种考虑了系统稳定性的编码方式。其作用是让系统更加稳定。与正常使用的方法没有多大的差别。
服务器端的代码:
internal sealed class PipeServer{ //声明一个命名管道 private readonly NamedPipeServerStream m_pipe = new NamedPipeServerStream( "Echo",PipeDirection.InOut,-1,PipeTransmissionMode.Message, PipeOptions.Asynchronous|PipeOptions.WriteThrough); public PipeServer(){ m_pipe.BeginWaitForConnection( } //定义当客户端连接后的回调方法 private void ClientConnected(IAsyncResult result){ new PipeServer(); //APM的结束 m_pipe.EndWaitForConnection(result); byte[] data = new byte[1000]; m_pipe.BeginRead(data,0,data.length,GotRequest,data); } //当数据读取完毕后的回调方法 private void GotRequest(IAsyncResult result){ //EndRead方法返回已经读取内容的字节数。若返回值为零,则代表到达流的末尾 int bytesread=m_pipe.EndRead(result); byte[] data=(byte[])result.AsyncState; data=Encoding.UTF8.GetBytes( Encoding.UTF8.GetString(data,0,bytesread).ToUpper().ToCharArray()); m_pipe.BeginWrite(data,0,data.Length,WriteDone,null); } private void WriteDone(IAsyncResult result){ m_pipe.EndWrite(result); m_pipe.Close(); } }
通过上面的这个例子,可以看到APM(Asynchronous Programming Model)的编写模式,在方法的内部,以Endxxx为开始,以BeginXXX为结束,在两者之间是相关的内容处理。
参数说明
对BeginXXX中方法的参数说明:方法的前三个参数是正常的,第四个参数是AsyncCallback,该委托的定义如下:
public delegate void AsyncCallback(IAsyncResult ar)
可以将
IAsyncResult看成是IRP的唯一标示。其唯一标示了一个I/O请求,系统在将请求放入驱动程序的队列中,并返回IAsyncResult对象的一个引用。
IAsyncResult是一个接口,而该接口具有几个属性,而实现了该接口的类也一定会存在这几个属性。这几个属性的具体定义如下:
IAsyncResult的AsyncState就可以用于数据传输,由beginxxx传入到endxxx中。下面是客户端的代码
internal sealed class PipeClient{ private readonly NamedPipeClientStream m_pipe; public PipeClient(string serverName,string message) { m_pipe=new NamedPipeClientStream(serverName,"Echo",PipeDirection.Inout,PipeOptions.Asynchronous|PipeOptions.WriteThrough); m_pipe.Connect(); //必须先连接,之后才能设定ReadMode m_pipe.ReadMode=PipeTransmissionMode.Message; byte[] output=Encoding.UTF8.GetBytes(message); m_pipe.BeginWrite(output,0,output.Length,WriteDone,null); } private void WriteDone(IAsyncResult result){ m_pipe.EndWrite(result); byte[] data=new byte[1000]; m_pipe.BeginRead(data,0,data.Length,GotResponse,data); } private void GotResponse(IAsyncResult result){ int bytesRead = m_pipe.EndRead(result); byte[] data=(byte[])result.AsyncState; Console.WriteLine("服务器的返回值"+Encoding.UTF8.GetString(data,0,data.Length)); m_pipe.Close(); } }
如何使用服务器端和客户端的程序
使用服务器端的代码如下:
public static void Main(){ for(int i=0;i<Environment.ProcessorCount;i++){ new PipeServer(); } Console.WriteLine("回车结束服务器程序"); Console.ReadLine(); }
使用客户端的代码如下
public static void Main(){ for(int i=0;i<100;i++) new PipeClient(".","请求"+i); Console.ReadLine(); }
以上的代码均来自《CLR via C#》的27.2小节。代码很简单,抄录很麻烦。肩膀都酸了。
小节
APM与其他正常的代码没有任何的差别,不管是异常处理还是其他方面,基本上一模一样。只有一个例外,就是在使用beginxxx和endxxx时略有差别。与多线程相比较,基本上没有什么太大的花样。
在27.2的开头,反而是讲了APM的关键信息
1、所有派生自system.io.stream并与硬件通信的类(包括filestream和networkstream)都提供APM
2、system.net.dns类提供了几个方法
3、system.net.sockets.socket类中提供符合APM编程方式的方法
另外,所有委托都定义了一个begininvoke方法。
总的来说,APM编码方式是一种考虑了系统稳定性的编码方式。其作用是让系统更加稳定。与正常使用的方法没有多大的差别。
相关文章推荐
- 《CLR via C#》读书笔记-异步编程(一)
- 《CLR via C#》读书笔记-异步编程(五)
- 《CLR via C#》读书笔记-异步编程(三)
- 《CLR via C#》读书笔记-异步编程(四)
- CLR via C# 读书笔记 3-6 比较APM和EAP(异步编程模型和基于事件的编程模式)
- CLR via C# 3 读书笔记(11):第2章 生成、打包、部署和管理应用程序与类型 — 2.3 元数据简介
- CLR via C# 3 读书笔记(13):第2章 生成、打包、部署和管理应用程序与类型 — 2.4 将模块组合为程序集(下)
- 【读书笔记】《框架设计(第2版)CLR Via C#》中两个比较有趣的知识点
- CLR via C# 3 读书笔记(14):第2章 生成、打包、部署和管理应用程序与类型 — 2.5 程序集版本资源信息
- 《CLR via C#》第23章 执行异步调用 读书笔记 part1
- CLR via C# 读书笔记(九)静态类,类型对象的生存周期
- 关于.NET(C#)中字符型(Char)与数字类型的转换, CLR via c# 读书笔记
- CLR via C# 3 读书笔记(6):第1章 CLR执行模型 — 1.6 框架类库
- CLR via C# 3 读书笔记(8):第1章 CLR执行模型 — 1.8 通用语言规范
- CLR via C# 读书笔记(二)new 操作符都干了些什么?
- CLR via C# 读书笔记(一)关于C#代码的编译和执行
- CLR via C# 3 读书笔记(7):第1章 CLR执行模型 — 1.7 通用类型系统
- CLR via C# 3 读书笔记(3):第1章 CLR执行模型 — 1.3 加载CLR
- CLR via C# 3 读书笔记(2):第1章 CLR执行模型 — 1.2 将托管模块组合为程序集
- CLR via C# 3 读书笔记(5):第1章 CLR执行模型 — 1.5 本地代码生成器工具:NGen.exe