文档章节

5.4 异步TCP编程(三)

张金富
 张金富
发布于 2012/07/09 19:03
字数 1088
阅读 338
收藏 2

#程序员薪资揭榜#你做程序员几年了?月薪多少?发量还在么?>>>

    5.4.3 使用异步方式调用同步方法

    .NET Framework提供了一种可以利用委托异步调用任何方法的技术,唯一的要求就是需要声明一个与要调用的方法具有相同签名的委托。对于任何一个方法,如果希望异步执行,最简单的方法就是通过调用委托的BeginInvoke方法开始异步执行,然后执行其他操作,最后调用委托的EndInvoke方法结束异步操作。由于EndInvoke直到异步操作完成后才返回,因此这种方法非常适合文件或网络操作。


    1、声明与要调用的方法具有相同签名的委托

    下面的代码说明了如何声明一个与要调用的方法具有相同签名的委托:

private BinaryReader br;
...
delegate void SendMessageDelegate(string message);
private void SendMessage(string message)
{
	try
	{
		bw.write(message);
		bw.flush();
	}
	catch
	{
		MessageBox.Show("发送失败!");
	}
}

    2、通过轮询方式检查异步调用是否完成

    声明和SendMessage方法具有相同签名的委托以后,公共语言运行时就会自动为该委托定义BeginInvoke方法和EndInvoke方法。然后就可以异步调用SendMessage方法了。

    调用BeginInvoke方法后,该方法会立即返回IAsyncResult类型的接口,从用户界面的服务线程中进行异步调用时,可以利用该接口的IsCompleted属性来通过轮询方式检查异步调用是否完成。在轮询过程中,BeginInvoke方法在ThreadPool中创建的线程会继续执行异步方法。例如:

private bool needExit;
...
SendMessageDelegate d = new SendMessageDelegate(SendMessage);
IAsyncResult result = d.BeginInvoke(message, null, null);
while(result.IsCompleted == false)
{
    if(needExit)
    {
        break;
    }
    Thread.Sleep(50);
}

    当然,代码中只是演示了调用BeginInvoke后,如何查询异步操作是否完成,实际上也可以在调用BeginInvoke后,执行其他任何代码。

    BeginInvoke方法除了与要异步执行的方法具有相同的参数外,另外还有两个可选参数,第1个参数是一个AsyncCallback委托,该委托引用在异步调用完成时要调用的方法;第2个参数是一个用户定义的对象,该对象将消息传入回调方法。在这段代码中,由于用不到这两个参数,所以全部将其设置为null。

    程序调用BeginInvoke后,会立即返回一个可用于监视异步调用进度的IAsyncResult 接口,并继续执行BeginInvoke方法后面的代码,而不是等待异步调用完成。

    3、使用EndInvoke结束异步调用

    EndInvoke方法用于检索异步调用的结果,并结束异步调用。调用BeginInvoke之后,随时可以调用该方法。如果异步调用尚未完成,则EndInvoke会一直阻止该调用线程,直到异步调用完成。例如,在退出轮询后,可以直接通过下面的代码结束异步调用:

d.EndInvoke(result);

    与其他异步操作的End方法相同,调用EndInvoke方法后,在EndInvoke方法返回前,由于有可能会引起调用EndInvoke方法的线程阻塞,所以一般不要从服务于用户界面的线程直接调用该方法,否则会在异步操作完成前,给用户一个界面无反应的错觉。为了使界面操作流畅,可以将上面的语句该为用其它线程执行,例如:

private struct SendMessageStates
{
    public SendMessageDelagate d;
    public IAsyncResult result;
}
private void AsyncSendMessage(string message)
{
    SendMessageDelagate d = new SendMessageDelagate(SendMessage);
    IAsyncResult result = d.BeginInvoke(message, null, null);
    while(result.IsCompleted == false)
    {
        Thread.Sleep(50);
    }
    SendMessageStates states = new SendMessageStates();
    states.d = d;
    states.result = result;
    Thread t = new Thread(FinishAsyncSendMessage);
    t.IsBackground = true;
    t.Start(states);
}
private void FinishAsyncSendMessage(object obj)
{
    SendMessageStates states = (SendMessageStates)obj;
    states.d.EndInvoke(states.result);
}

    4、在异步调用中传递多个参数

    在异步调用中,如果有多个参数信息,这些参数还可以使用out和ref关键字。例如:

delegate void ReceiveMessageDelegate(out string receiveMessage);
private void ReceiveMessage(out string receiveMessage)
{
    receiveMessage = null;
    try
    {
        receiveMessage = br.ReadString();
    }
    catch(Exception ex)
    {
        MessageBox.Show(ex.message);
    }
}
...
ReceiveMessageDelegate d = new ReceiveMessageDelegate(ReceiveMessage);
IAsyncResult result = d.BeginInvoke(out receiveString, null, null);
while(result.IsCompleted == false)
{
    Thread.Sleep(250);
}
d.EndInvoke(out receiveString, result);

    可见,使用异步方式调用同步方法,既实现了任何方法的异步调用,又可以轻而易举地解决异步调用中的同步问题,对于相对比较复杂的异步处理过程,这是首选的方法,也是最简单、最方便的方法。

本文转载自网络

张金富

张金富

粉丝 55
博文 9
码字总数 5858
作品 0
烟台
程序员
私信 提问
加载中

评论(0)

php搭建swooleTCP服务器

这次的swoole学习,比较缓慢 也由于这些几天事比较多,晚上没去学习,swoole的笔记也一直在没编写,下面简单介绍和应用下swoole swoole是什么? 异步、并行、高性能 纯C编写 php扩展 swoole...

osc_57loaj8m
2018/12/22
6
0
C#网络编程系列文章(一)之Socket实现异步TCP服务器

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

zhujunxxxxx
2015/03/14
0
0
C#网络编程系列文章(二)之Socket实现同步TCP服务器

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

zhujunxxxxx
2015/03/14
0
0
花花世界欢乐多/swoole-worker

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

花花世界欢乐多
2017/08/15
0
0
C#网络编程系列文章(三)之TcpListener实现异步TCP服务器

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

zhujunxxxxx
2015/03/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

文献速递20200524

一 文献题目:Characterizing the Causal Pathway for Genetic Variants Associated with Neurological Phenotypes Using Human Brain-Derived Proteome Data 不想看英文题目:使用人脑蛋白质......

osc_mbhfa1vl
21分钟前
9
0
【Java入门】JDK安装和环境变量配置(Win7版)

系统环境:Windows7 x64 安装JDK和JRE版本:1.8.0_191 1、下载JDK安装包 Oracle官网下载网址:https://www.oracle.com/technetwork/java/javase/downloads/index.html 选择需要下载的JDK版本...

osc_s7aj86hu
23分钟前
11
0
Android Q 指纹解锁流程

Android Q 指纹解锁流程 // Authentation Finger Schedule: (close Screen, Authentation with finger(Success))        // PhoneWindowManager        mKeyguardDelegate.onStar......

osc_0qnrwmy3
24分钟前
12
0
List的扩容机制,你真的明白吗?

一:背景 1. 讲故事 在前一篇大内存排查中,我们看到了Dictionary正在做扩容操作,当时这个字典的count=251w,你把字典玩的66飞起,其实都是底层为你负重前行,比如其中的扩容机制,当你遇到...

osc_34b9n45c
26分钟前
14
0
2020.04.12软件更新公告

原创软件区升级ComicsViewer、DjVuToy、Pdg2Pic、PdgRenamer、PdgThumbViewer

osc_6tgtqi6v
27分钟前
23
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部