5.4 异步TCP编程(一)
5.4 异步TCP编程(一)
张金富 发表于5年前
5.4 异步TCP编程(一)
  • 发表于 5年前
  • 阅读 317
  • 收藏 3
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

摘自《C#网络应用编程》(第2版)
看到网上资料很少,做个摘录,如有版权问题,请告知。

    利用TcpListener类和TcpClient类在同步方式下接收、发送数据以及监听客户端连接时,在操作没有完成之前一直处于阻塞状态,这种同步TCP编程模式在开启的前台线程不太多的情况下是比较合适的。但是,如果开启的前台线程较多,系统的性能就会受到影响。这种情况下,最好的办法是使用异步操作。

    实际上,在大型的应用系统中,多数都采用异步工作方式,因此希望读者尽可能掌握本节的主要设计思想,为编写复杂的网络应用程序打好基础。

5.4.1 异步设计模式概述

    所谓异步操作方式,就是我们希望让某个工作开始以后能在这个工作尚未完成的时候继续处理其他工作。异步操作一般在单独的线程中进行,调用异步方法异步执行某个操作时,可同时继续执行该异步方法后面的代码。

    使用异步操作方式编写程序就是异步编程。

    异步编程有两种模式,一种是基于事件的异步设计模式,另一种是基于IAsyncResult的异步设计模式。基于事件的异步设计模式封装了异步编程的复杂度,简化了异步设计的难度,理解起来比较直观。基于IAsyncResult的异步设计模式提供了更灵活的控制功能,但实现代码理解起来相对困难一些。

    1、基于事件的异步设计模式

    基于事件的异步设计模式用事件驱动模型实现异步方法,这种模式用单独的线程在后台执行耗时的任务,当后台任务完成时,就自动触发对应的事件。该模式既具有多线程应用程序的优点,同时也隐匿了多线程设计中固有的许多复杂问题。BackgroundWorker组件就是用这种模式提供的对异步操作封装后的、适用于一般异步设计的组件,利用它可以完成绝大多数异步设计任务,而不需要考虑复杂的异步操作细节。除此之外,还有其他的控件和组件也提供了基于事件的异步设计模式,如PictureBox控件等。

    编写不太复杂的异步操作的应用程序时,建议尽量使用基于事件的异步设计模式。因为它能有效的提高项目开发效率和质量,同时也降低了异步编程的复杂度。

    2、基于IAsyncResult的异步设计模式

    TcpListenerTcpClient除了提供同步模式下对应的方法,还为基于IAsyncResult的异步设计模式提供了对应的方法,以便为程序员提供更加灵活的异步编程支持。

    (1)基本原理。基于IAsyncResult的异步设计模式通过前缀分别为“Begin”和“End”的两个方法实现开始和结束异步操作,每个Begin方法都必须有一个与其对应的End方法,如BeginAcceptTcpClientEndAcceptTcpClient方法等。程序在调用Begin方法后,调用该方法的线程会继续执行其下面的语句,同时该方法用另一个单独的线程执行异步操作,当异步操作完成后,会返回一个实现IAsyncResult接口的对象,该对象存储了有关异步操作的信息。这些信息包括以下内容。

    AsyncState:包含异步操作需要的状态信息,如果不需要状态信息,可以将此设置为null。
    AsyncWaitHandle:用于在异步操作完成前阻止程序执行。
    CompletedSynchronously:指示异步操作是否在用于调用Begin前缀的线程上完成,而不是在单独的ThreadPool线程上完成。
    IsCompleted:一个布尔值,指示异步操作是否已完成。

    调用Begin方法后,程序还应该调用End方法来结束异步操作。

    (2)AsyncCallback委托。AsyncCallback委托用于在异步操作完成时调用指定的回调方法。在基于IAsyncResult的异步操作方式下,由于程序可以在启动异步操作后继续执行其他代码,因此必须有一种机制,以保证该异步操作完成时能及时通知调用者。AsyncCallback委托就是为实现这种机制而提供的。

    回调方法是在程序中事先定义的,在回调方法中,通过End方法获取Begin方法的返回值和所有输入/输出参数,从而达到在异步操作方式下完成参数传递的目的。

    但是,由于基于IAsyncResult的异步设计模式控制同步问题非常麻烦,而且代码难以理解。在实际设计中,一般不使用AsyncCallback委托处理异步操作的结果,而是利用轮询方式来判断异步操作是否完成。

    具体实现思路为:调用Begin方法得到IAsyncResult对象,再循环判断该对象的IsCompleted属性,来决定异步操作是否完成。在这种情况下,将Begin方法的AsyncCallback参数设置为null即可。

    在本章后面的异步编程例子中,我们还会学习具体设计方法。

标签: 异步 多线程 .net
共有 人打赏支持
粉丝 54
博文 6
码字总数 95
×
张金富
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: