文档章节

5.4 异步TCP编程(一)

张金富
 张金富
发布于 2012/07/07 16:31
字数 1403
阅读 320
收藏 3
点赞 0
评论 0

摘自《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即可。

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

本文转载自:

共有 人打赏支持
张金富
粉丝 54
博文 6
码字总数 95
作品 0
烟台
程序员
5.4 异步TCP编程(二)

5.4.2 异步TCP应用编程的一般方法(本节可以忽略) 使用异步TCP编程时,除了套接字有对应的异步操作方式外,TcpListener和TcpClient类均提供了返回结果为IAsyncResult类型的异步操作的方法。...

张金富 ⋅ 2012/07/07 ⋅ 0

C#网络编程系列文章(一)之Socket实现异步TCP服务器

原创性声明 本文作者:小竹zz 本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 转载请注明出处 文章系列目录 C#网络编程系列文章(一)之Socket实现异步TCP服务器 C#网络编...

zhujunxxxxx ⋅ 2015/03/14 ⋅ 0

花花世界欢乐多/swoole-worker

swoole-worker 关于本项目 此项目是workerman(v3.4.5)的swoole移植版本,移除了对pcntl,libevent,event,ev扩展的依赖,转而使用swoole提供的swooleprocess和swooleevent,定时器采用swoole的s...

花花世界欢乐多 ⋅ 2017/08/15 ⋅ 0

C#网络编程系列文章(二)之Socket实现同步TCP服务器

原创性声明 本文作者:小竹zz 本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 转载请注明出处 文章系列目录 C#网络编程系列文章(一)之Socket实现异步TCP服务器 C#网络编...

zhujunxxxxx ⋅ 2015/03/14 ⋅ 0

5.4 异步TCP编程(三)

5.4.3 使用异步方式调用同步方法 .NET Framework提供了一种可以利用委托异步调用任何方法的技术,唯一的要求就是需要声明一个与要调用的方法具有相同签名的委托。对于任何一个方法,如果希望...

张金富 ⋅ 2012/07/09 ⋅ 0

C#网络编程系列文章(三)之TcpListener实现异步TCP服务器

原创性声明 本文作者:小竹zz 本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 转载请注明出处 文章系列目录 C#网络编程系列文章(一)之Socket实现异步TCP服务器 C#网络编...

zhujunxxxxx ⋅ 2015/03/14 ⋅ 0

C#网络编程系列文章(四)之TcpListener实现同步TCP服务器

原创性声明 本文作者:小竹zz 本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 转载请注明出处 文章系列目录 C#网络编程系列文章(一)之Socket实现异步TCP服务器 C#网络编...

zhujunxxxxx ⋅ 2015/03/15 ⋅ 0

C#网络编程系列文章(七)之UdpClient实现异步UDP服务器

原创性声明 本文作者:小竹zz 本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 转载请注明出处 文章系列目录 C#网络编程系列文章(一)之Socket实现异步TCP服务器 C#网络编...

zhujunxxxxx ⋅ 2015/03/16 ⋅ 0

C#网络编程系列文章(五)之Socket实现异步UDP服务器

原创性声明 本文作者:小竹zz 本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 转载请注明出处 文章系列目录 C#网络编程系列文章(一)之Socket实现异步TCP服务器 C#网络编...

zhujunxxxxx ⋅ 2015/03/15 ⋅ 0

php异步高并发扩展swoole-1.6.10版发布

简介: swoole是一个php版本的异步、高并发扩展,是国人被php官方pecl包收录的力作之一。 swoole项目在春节前发布了1.6.10版本: 内核更新: - Enabled by default asyncmysql (5.4版本默认开...

半桶水_桶哥 ⋅ 2014/01/26 ⋅ 31

没有更多内容

加载失败,请刷新页面

加载更多

下一页

mysql5.7系列修改root默认密码

操作系统为centos7 64 1、修改 /etc/my.cnf,在 [mysqld] 小节下添加一行:skip-grant-tables=1 这一行配置让 mysqld 启动时不对密码进行验证 2、重启 mysqld 服务:systemctl restart mysql...

sskill ⋅ 9分钟前 ⋅ 0

Intellij IDEA神器常用技巧六-Debug详解

在调试代码的时候,你的项目得debug模式启动,也就是点那个绿色的甲虫启动服务器,然后,就可以在代码里面断点调试啦。下面不要在意,这个快捷键具体是啥,因为,这个keymap是可以自己配置的...

Mkeeper ⋅ 13分钟前 ⋅ 0

zip压缩工具、tar打包、打包并压缩

zip 支持压缩目录 1.在/tmp/目录下创建目录(study_zip)及文件 root@yolks1 study_zip]# !treetree 11└── 2 └── 3 └── test_zip.txt2 directories, 1 file 2.yum...

蛋黄Yolks ⋅ 16分钟前 ⋅ 0

聊聊HystrixThreadPool

序 本文主要研究一下HystrixThreadPool HystrixThreadPool hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/HystrixThreadPool.java /** * ThreadPool used to executed {@link Hys......

go4it ⋅ 35分钟前 ⋅ 0

容器之上传镜像到Docker hub

Docker hub在国内可以访问,首先要创建一个账号,这个后面会用到,我是用126邮箱注册的。 1. docker login List-1 Username不能使用你注册的邮箱,要用使用注册时用的username;要输入密码 ...

汉斯-冯-拉特 ⋅ 41分钟前 ⋅ 0

SpringBoot简单使用ehcache

1,SpringBoot版本 2.0.3.RELEASE ①,pom.xml <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.3.RELE......

暗中观察 ⋅ 42分钟前 ⋅ 0

监控各项服务

比如有三个服务, 为了减少故障时间,增加监控任务,使用linux的 crontab 实现. 步骤: 1,每个服务写一个ping接口 监控如下内容: 1,HouseServer 是否正常运行,所以需要增加一个ping的接口 ; http...

黄威 ⋅ 45分钟前 ⋅ 0

Spring源码解析(八)——实例创建(下)

前言 来到实例创建的最后一节,前面已经将一个实例通过不同方式(工厂方法、构造器注入、默认构造器)给创建出来了,下面我们要对创建出来的实例进行一些“加工”处理。 源码解读 回顾下之前...

MarvelCode ⋅ 46分钟前 ⋅ 0

nodejs __proto__跟prototype

前言 nodejs中完全没有class的这个概念,这点跟PHP,JAVA等面向对象的语言很不一样,没有class跟object的区分,那么nodejs是怎么样实现继承的呢? 对象 对象是由属性跟方法组成的一个东西,就...

Ai5tbb ⋅ 52分钟前 ⋅ 0

Ubuntu16.04 PHP7.0 不能用MYSQLi方式连接MySQL5.7数据库

Q: Ubuntu16.04 PHP7.0 不能用MYSQLi方式连接MySQL5.7数据库 A: 执行以下2条命令解决: apt-get install php-mysql service apache2 restart php -m 执行后会多以下4个模块: mysqli mysqlnd...

SamXIAO ⋅ 54分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部