精华内容
下载资源
问答
  • 考虑以下电路,当触发器的D数据输入相对于clk来说是异步的,再这种情况下,因为不知道什么时候会有异步输入的信号、输入信号什么时候撤销,这将导致在clk上升沿来临时建立和保持时间不满足,从而导致输出Q的数据...

    考虑以下电路,当触发器的D端数据输入相对于clk来说是异步的,再这种情况下,因为不知道什么时候会有异步输入的信号、输入信号什么时候撤销,这将导致在clk上升沿来临时建立和保持时间不满足,从而导致输出端Q的数据不稳定。
    在这里插入图片描述
    对于该电路来说,D端信号和清零信号均是相对于clk来说是异步信号,因此两个信号均需要考虑,下面进行分析。
    一.异步输入信号导致亚稳态分析
    常见的同步电路如下,采用两级寄存器拍了拍,实现信号跨时钟域同步。
    在这里插入图片描述
    但这样的电路只适用于异步输入的脉宽大于时钟周期的情况,当输入脉宽太窄时,clk可能出现采漏情况。
    因此考虑以下电路同步,当输入窄脉冲时,该电路能正确采集并输出一个clk周期的高电平。
    在这里插入图片描述
    当没有输入信号时,电路稳定的状态输出如下所示
    在这里插入图片描述
    可见,该电路正常工作,等待异步输入的上升沿触发第一级DFF。当窄脉冲输入时,电路的状态如下
    在这里插入图片描述
    由于输入脉宽窄,在跳高又跳低时clk时钟未到上升沿,所以该电路接下来等待时钟上升沿。
    时钟上升沿到来是,电路状态如下
    在这里插入图片描述
    由于第一级和第二级触发器之间时钟不同,因此有很大概率产生亚稳态;但第三级触发器是正常的所以输出为0,反馈的组合电路状态还是没改变。
    当下一个时钟上升沿到来时,电路的状态如下
    在这里插入图片描述
    第三级触发器可能输出1,也可能输出0,当输出为0时,组合电路状态未变,当输出为1时,电路改变如下
    在这里插入图片描述
    由于同步输出为1,导致组合电路产生了清零信号,导致第一,二级触发器清零。但也正是由于清零信号的存在,导致同步输出只产生了一个clk周期宽度的高电平。因此该电路可以将异步输入的窄脉冲,拓宽为clk周期的信号。
    再回头查看两级寄存器同步电路,如下所示
    在这里插入图片描述
    当data_clka输入为一个clk_a周期脉宽时,clk_b可能未能正确采集到数据,因此需要对输入的脉宽进行延长。如下所示电路
    在这里插入图片描述
    将data_clka一个周期的高电平时间延长为多个周期,以便于clk_b采集。
    二.异步复位信号导致的亚稳态分析
    电路图如下
    在这里插入图片描述
    由于时钟和数据是在同一时钟域的,所以不用考虑由于数据输入产生的亚稳态。复位信号有效时输出为0,此时输出不会产生亚稳态,但当复位信号结束时,clk上升沿可能恰好有效,此时采集到rst的电平未知,从而产生出亚稳态。
    因此为了防止复位信号产生的亚稳态,从而设计出以下电路
    在这里插入图片描述
    当rst信号为高电平时,电路正常工作,电路的状态如下所示
    在这里插入图片描述
    当rst信号有效时,电路进行复位,状态如下
    在这里插入图片描述
    各级触发器复位,等待复位信号结束,当复位结束时,电路状态如下
    在这里插入图片描述
    当rst信号复位结束时,clk时钟上升沿到来,由于rst信号在跳变建立时间不满足,采集到rst信号未知,从而导致第一级触发器输出值未知,即第一级触发器产生亚稳态。对于第二级触发器来说,由于在clk上升沿来之前其D端为0,Q端为0,当clk上升沿有效时,虽然对rst采样到未知电平,但此时触发器还是会输出0,因为没有让触发器跳1的条件。即采集到rst=0,触发器输出为0,采集到rst=1,输入D=0,所以触发器还是输出为0。这也就是异步复位、同步释放电路。
    这点类似三目运算符,即表达式:assign out= sel?a:b;当a=4’b1010,b=4’b1001,sel=x时,输出out=4’b10xx。

    展开全文
  • 代码号为”merlin”的j2se1.4带来了一些激动人心的新特性,诸如对正则表达式的支持,异步输入输出流,通道(channel),字符集等.虽然该版本还处在测试阶段,但这些新特性早已让开发人员们跃跃欲试.在merlin发布之前,异步...

    代码号为”merlin”的j2se1.4带来了一些激动人心的新特性,诸如对正则表达式的支持,异步输入输出流,通道(channel),字符集等.虽然该版本还处在测试阶段,但这些新特性早已让开发人员们跃跃欲试.在merlin发布之前,异步输入输出流的应用还只是c,c++程序员的特殊武器;在merlin中引入异步输入输出机制之后,java程序员也可以利用它完成很多简洁却是高质量的代码了.本文将介绍怎样使用异步输入输出流来编写socket进程通信程序.同步?异步输入输出机制的引入 在merlin之前,编写socket程序是比较繁琐的工作.因为输入输出都必须同步.这样,对于多客户端客户/服务器模式,不得不使用多线程.即为每个连接的客户都分配一个线程来处理输入输出.由此而带来的问题是可想而知的.程序员不得不为了避免死锁,线程安全等问题,进行大量的编码和测试.很多人都在抱怨为什么不在java中引入异步输入输出机制.比较官方的解释是,任何一种应用程序接口的引入,都必须兼容任何操作平台.因为java是跨平台的.而当时支持异步输入输出机制的操作平台显然不可能是全部.自java 2 platform以后,分离出j2se,j2me,j2ee三种不同类型的应用程序接口,以适应不同的应用开发.java标准的制订者们意识到了这个问题,并且支持异步输入输出机制的操作平台在当今操作平台中处于主流地位.于是,jdk(j2se) 的第五次发布中引入了异步输入输出机制.以前的socket进程通信程序设计中,一般客户端和服务器端程序设计如下: 服务器端: //服务器端监听线程while (true) <.............socket clientsocket;clientsocket = socket.accept(); //取得客户请求socket,如果没有//客户请求连接,线程在此处阻塞//用取得的socket构造输入输出流printstream os = new printstream(new bufferedoutputstream(clientsocket.getoutputstream(),1024), false);bufferedreader is = new bufferedreader(new inputstreamreader(clientsocket.getinputstream()));//创建客户会话线程,进行输入输出控制,为同步机制new clientsession();.......>客户端: ............clientsocket = new socket(hostname, listenport);//连接服务器套接字//用取得的socket构造输入输出流printstream os = new printstream(new bufferedoutputstream(clientsocket.getoutputstream(),1024), false);bufferedreader is = new bufferedreader(new inputstreamreader(clientsocket.getinputstream()));//进行输入输出控制....... 以上代码段只是用同步机制编写socket进程通信的一个框架,实际上要考虑的问题要复杂的多(有兴趣的读者可以参考我的一篇文章《internet 实时通信系统设计与实现》)。将这样一个框架列出来,只是为了与用异步机制实现的socket进程通信进行比较。下面将介绍使用异步机制的程序设计。用异步输入输出流编写socket进程通信程序 在merlin中加入了用于实现异步输入输出机制的应用程序接口包:java.nio(新的输入输出包,定义了很多基本类型缓冲(buffer)),java.nio.channels(通道及选择器等,用于异步输入输出),java.nio.charset(字符的编码解码)。通道(channel)首先在选择器(selector)中注册自己感兴趣的事件,当相应的事件发生时,选择器便通过选择键(selectionkey)通知已注册的通道。然后通道将需要处理的信息,通过缓冲(buffer)打包,编码/解码,完成输入输出控制。通道介绍: 这里主要介绍serversocketchannel和 socketchannel.它们都是可选择的(selectable)通道,分别可以工作在同步和异步两种方式下(注意,这里的可选择不是指可以选择两种工作方式,而是指可以有选择的注册自己感兴趣的事件)。可以用channel.configureblocking(boolean )来设置其工作方式。与以前版本的api相比较,serversocketchannel就相当于serversocket(serversocketchannel封装了serversocket),而socketchannel就相当于socket(socketchannel封装了socket)。当通道工作在同步方式时,编程方法与以前的基本相似,这里主要介绍异步工作方式。所谓异步输入输出机制,是指在进行输入输出处理时,不必等到输入输出处理完毕才返回。所以异步的同义语是非阻塞(none blocking)。在服务器端,serversocketchannel通过静态函数open()返回一个实例serverchl。然后该通道调用serverchl.socket().bind()绑定到服务器某端口,并调用register(selector sel, selectionkey.op_accept)注册op_accept事件到一个选择器中(serversocketchannel只可以注册op_accept事件)。当有客户请求连接时,选择器就会通知该通道有客户连接请求,就可以进行相应的输入输出控制了;在客户端,clientchl实例注册自己感兴趣的事件后(可以是op_connect,op_read,op_write的组合),调用clientchl.connect(inetsocketaddress )连接服务器然后进行相应处理。注意,这里的连接是异步的,即会立即返回而继续执行后面的代码。选择器和选择键介绍: 选择器(selector)的作用是:将通道感兴趣的事件放入队列中,而不是马上提交给应用程序,等已注册的通道自己来请求处理这些事件。换句话说,就是选择器将会随时报告已经准备好了的通道,而且是按照先进先出的顺序。那么,选择器是通过什么来报告的呢?选择键(selectionkey)。选择键的作用就是表明哪个通道已经做好了准备,准备干什么。你也许马上会想到,那一定是已注册的通道感兴趣的事件。不错,例如对于服务器端serverchl来说,可以调用key.isacceptable()来通知serverchl有客户端连接请求。相应的函数还有:selectionkey.isreadable(),selectionkey.iswritable()。一般的,在一个循环中轮询感兴趣的事件(具体可参照下面的代码)。如果选择器中尚无通道已注册事件发生,调用selector.select()将阻塞,直到有事件发生为止。另外,可以调用selectnow()或者select(long timeout)。前者立即返回,没有事件时返回0值;后者等待timeout时间后返回。一个选择器最多可以同时被63个通道一起注册使用。应用实例: 下面是用异步输入输出机制实现的客户/服务器实例程序――程序清单1(限于篇幅,只给出了服务器端实现,读者可以参照着实现客户端代码): 程序类图public class nblockingserver public void initialize() throws ioexception //结束时释放资源public void finalize() throws ioexception //将读入字节缓冲的信息解码public string decode( bytebuffer bytebuffer ) throws charactercodingexception //监听端口,当通道准备好时进行相应操作public void portlistening() throws ioexception, interruptedexception else if ( key.iswritable() ) >>>//对通道的写操作public void writetochannel( socketchannel channel, string message ) throws ioexception //对通道的读操作public void readfromchannel( socketchannel channel, clientchinstance clientinstance )throws ioexception, interruptedexception else >>//该类封装了怎样对客户端的通道进行操作,具体实现可以通过重载execute()方法public class clientchinstance public void execute() throws ioexception //当一行没有结束时,将当前字窜置于缓冲尾public void append( string values ) >//主程序public static void main( string[] args ) catch ( exception e ) try catch ( exception e ) >>程序清单1小结: 从以上程序段可以看出,服务器端没有引入多余线程就完成了多客户的客户/服务器模式。该程序中使用了回调模式(callback),细心的读者应该早就看出来了。需要注意的是,请不要将原来的输入输出包与新加入的输入输出包混用,因为出于一些原因的考虑,这两个包并不兼容。即使用通道时请使用缓冲完成输入输出控制。该程序在windows2000,j2se1.4下,用telnet测试成功。参考文献: 《javatm 2 platform, standard edition, v 1.4.0 api specification》

    展开全文
  • 运用异步输入输出流编写Socket进程通信

    运用异步输入输出流编写Socket进程通信

    developerWorks
    文档选项
    将此页作为电子邮件发送

    将此页作为电子邮件发送


    New site feature

    Kick-start your Java apps with free software


    级别: 初级

    杨健中南工业大学

    2001 年 11 月 06 日

    摘要:代码号为”Merlin”的J2SE1.4带来了一些激动人心的新特性,诸如对正则表达式的支持,异步输入输出流,通道(Channel),字符集等.虽然该版本还处在测试阶段,但这些新特性早已让开发人员们跃跃欲试.在Merlin发布之前,异步输入输出流的应用还只是C,C++程序员的特殊武器;在Merlin中引入异步输入输出机制之后,Java程序员也可以利用它完成很多简洁却是高质量的代码了.本文将介绍怎样使用异步输入输出流来编写Socket进程通信程序.

    同步?异步输入输出机制的引入

    在Merlin之前,编写Socket程序是比较繁琐的工作.因为输入输出都必须同步.这样,对于多客户端客户/服务器模式,不得不使用多线程.即为每个连接的客户都分配一个线程来处理输入输出.由此而带来的问题是可想而知的.程序员不得不为了避免死锁,线程安全等问题,进行大量的编码和测试.很多人都在抱怨为什么不在Java中引入异步输入输出机制.比较官方的解释是,任何一种应用程序接口的引入,都必须兼容任何操作平台.因为Java是跨平台的.而当时支持异步输入输出机制的操作平台显然不可能是全部.自Java 2 Platform以后,分离出J2SE,J2ME,J2EE三种不同类型的应用程序接口,以适应不同的应用开发.Java标准的制订者们意识到了这个问题,并且支持异步输入输出机制的操作平台在当今操作平台中处于主流地位.于是,Jdk(J2SE) 的第五次发布中引入了异步输入输出机制.

    以前的Socket进程通信程序设计中,一般客户端和服务器端程序设计如下:

    1. 服务器端:


    2. 客户端:

      以上代码段只是用同步机制编写Socket进程通信的一个框架,实际上要考虑的问题要复杂的多(有兴趣的读者可以参考我的一篇文章《Internet 实时通信系统设计与实现》)。将这样一个框架列出来,只是为了与用异步机制实现的Socket进程通信进行比较。下面将介绍使用异步机制的程序设计。





    回页首


    用异步输入输出流编写Socket进程通信程序

    在Merlin中加入了用于实现异步输入输出机制的应用程序接口包:java.nio(新的输入输出包,定义了很多基本类型缓冲(Buffer)),java.nio.channels(通道及选择器等,用于异步输入输出),java.nio.charset(字符的编码解码)。通道(Channel)首先在选择器(Selector)中注册自己感兴趣的事件,当相应的事件发生时,选择器便通过选择键(SelectionKey)通知已注册的通道。然后通道将需要处理的信息,通过缓冲(Buffer)打包,编码/解码,完成输入输出控制。

    通道介绍:

    这里主要介绍ServerSocketChannel和 SocketChannel.它们都是可选择的(selectable)通道,分别可以工作在同步和异步两种方式下(注意,这里的可选择不是指可以选择两种工作方式,而是指可以有选择的注册自己感兴趣的事件)。可以用channel.configureBlocking(Boolean )来设置其工作方式。与以前版本的API相比较,ServerSocketChannel就相当于ServerSocket(ServerSocketChannel封装了ServerSocket),而SocketChannel就相当于Socket(SocketChannel封装了Socket)。当通道工作在同步方式时,编程方法与以前的基本相似,这里主要介绍异步工作方式。

    所谓异步输入输出机制,是指在进行输入输出处理时,不必等到输入输出处理完毕才返回。所以异步的同义语是非阻塞(None Blocking)。在服务器端,ServerSocketChannel通过静态函数open()返回一个实例serverChl。然后该通道调用serverChl.socket().bind()绑定到服务器某端口,并调用register(Selector sel, SelectionKey.OP_ACCEPT)注册OP_ACCEPT事件到一个选择器中(ServerSocketChannel只可以注册OP_ACCEPT事件)。当有客户请求连接时,选择器就会通知该通道有客户连接请求,就可以进行相应的输入输出控制了;在客户端,clientChl实例注册自己感兴趣的事件后(可以是OP_CONNECT,OP_READ,OP_WRITE的组合),调用clientChl.connect(InetSocketAddress )连接服务器然后进行相应处理。注意,这里的连接是异步的,即会立即返回而继续执行后面的代码。

    选择器和选择键介绍:

    选择器(Selector)的作用是:将通道感兴趣的事件放入队列中,而不是马上提交给应用程序,等已注册的通道自己来请求处理这些事件。换句话说,就是选择器将会随时报告已经准备好了的通道,而且是按照先进先出的顺序。那么,选择器是通过什么来报告的呢?选择键(SelectionKey)。选择键的作用就是表明哪个通道已经做好了准备,准备干什么。你也许马上会想到,那一定是已注册的通道感兴趣的事件。不错,例如对于服务器端serverChl来说,可以调用key.isAcceptable()来通知serverChl有客户端连接请求。相应的函数还有:SelectionKey.isReadable(),SelectionKey.isWritable()。一般的,在一个循环中轮询感兴趣的事件(具体可参照下面的代码)。如果选择器中尚无通道已注册事件发生,调用Selector.select()将阻塞,直到有事件发生为止。另外,可以调用selectNow()或者select(long timeout)。前者立即返回,没有事件时返回0值;后者等待timeout时间后返回。一个选择器最多可以同时被63个通道一起注册使用。

    应用实例:

    下面是用异步输入输出机制实现的客户/服务器实例程序�D�D程序清单1(限于篇幅,只给出了服务器端实现,读者可以参照着实现客户端代码):


    程序类图
    程序类图

    程序清单1
    展开全文
  • 服务器端异步 Web 方法Matt PowellMicrosoft Corporation 2002年10月2日 摘要:Matt Powell 介绍了如何在服务器使用异步 Web 方法,来创建高性能的 Microsoft ASP.NET Web 服务。 简介在九月份的第三篇专栏(英文...

    服务器端异步 Web 方法


    Matt Powell
    Microsoft Corporation
    2002年10月2日

     

    摘要:Matt Powell 介绍了如何在服务器端使用异步 Web 方法,来创建高性能的 Microsoft ASP.NET Web 服务。


    简介

    九月份的第三篇专栏(英文)中,我谈到了利用 Microsoft® .NET Framework 的客户端功能通过 HTTP 异步调用 Web 服务的问题。这种调用 Web 服务的方法非常有用,使用时不必锁定您的应用程序或产生过多后台线程。现在我们了解一下在服务器端提供类似功能的异步 Web 方法。异步 Web 方法在编写 ISAPI 扩展方面具有与 HSE_STATUS_PENDING 方法类似的高性能,但不需要为管理自己的线程池编写代码,同时又具有以托管代码方式运行的所有优点。

    首先我们考虑一下常规的同步 Microsoft® ASP.NET Web 方法。当您从同步 Web 方法返回时,将发送对该方法的响应。如果需要较长的时间来完成请求,则处理请求的线程会一直被占用,直到方法调用结束。不幸的是,多数较长的调用是由较长的数据库查询或对另一个 Web 服务的调用等事件引起的。例如,如果您调用数据库,当前线程会一直等待调用完成。线程无事可做,只是等待,直至听到查询的返回。当线程等待完成对 TCP 套接字或后端 Web 服务的调用时,也会出现类似的问题。

    让线程处于等待状态很不好,特别是在服务器的运行压力很大的情况下。等待中的线程不会进行任何有效工作,例如为其他请求提供服务。我们需要找到一种方法,能够在服务器上开始较长的后台进程,同时又能将当前线程返回到 ASP.NET 进程池。然后,当较长的后台进程完成时,我们调用一个回调函数,结束对请求的处理,并通过某种方式通知 ASP.NET 请求已完成。实际上,这种功能可由 ASP.NET 使用异步 Web 方法提供。

    异步 Web 方法的工作原理

    当您使用 Web 方法编写典型的 ASP.NET Web 服务时,Microsoft® Visual Studio® .Net 只是编译您的代码以创建程序集;当收到对其 Web 方法的请求时,将调用该程序集。程序集本身并不知道关于 SOAP 的任何事情。因此,当您的应用程序首次启动时,ASMX 处理程序必须反映您的程序集,以确定提供哪些 Web 方法。对于常规的同步请求,这些操作都很简单:找出哪些方法具有关联的 WebMethod 属性、基于 SOAPAction HTTP 标头来设置调用正确方法的逻辑。

    对于异步请求,在反映过程中,ASMX 处理程序寻找具有某种签名并将签名识别为异步的 Web 方法。该处理程序将寻找符合以下规则的方法对:

    • BeginXXXEndXXX Web 方法,其中 XXX 是任意字符串,表示要提供的方法的名称。
    • BeginXXX 函数返回一个 IAsyncResult 接口,并分别接受 AsyncCallback 和一个对象,作为其最后两个输入参数。
    • EndXXX 函数接受一个 IAsyncResult 接口,作为其唯一的参数。
    • 两个方法都必须使用 WebMethod 属性进行标识。

    如果 ASMX 处理程序发现两个方法符合上述所有条件,则将方法 XXX 作为常规的 Web 方法在其 WSDL 中提供。该方法将接受在 BeginXXX 的签名中的 AsyncCallback 参数之前定义的参数作为输入,并返回由 EndXXX 函数返回的内容。因此,如果某个 Web 方法具有如下同步声明:

        [WebMethod]
        public string LengthyProcedure(int milliseconds) {...}
    

    则异步声明将为:

        [WebMethod]
        public IAsyncResult BeginLengthyProcedure(
                                int milliseconds, 
                                AsyncCallback cb, 
                                object s) {...}
    
        [WebMethod]
        public string EndLengthyProcedure(IAsyncResult call) {...}
    

    每个方法的 WSDL 都是相同的。

    在 ASMX 处理程序反映程序集并检测到某个异步 Web 方法后,它必须以不同于处理同步请求的方式处理对该方法的请求。它将调用 BeginXXX 方法,而不是某个简单方法。它将传入的请求还原序列化到要传递到函数的参数中(与处理同步请求时一样);但是它还将指针传递到一个内部回调函数(作为 BeginXXX 方法的额外 AsyncCallback 参数)。

    这种方法类似于 .NET Framework 中 Web 服务客户端应用程序的异步编程模式。如果客户端支持异步 Web 服务调用,则可以为客户端计算机释放占用的线程;如果服务器端支持异步 Web 服务调用,则可以释放服务器计算机上占用的线程。但这里有两个关键的区别。首先,不是由服务器代码调用 BeginXXXEndXXX 函数,而是由 ASMX 处理程序调用。其次,您要为 BeginXXX EndXXX 函数编写代码,而不能使用由 WSDL.EXE 或 Visual Studio .NET 中的 Add Web Reference(添加 Web 引用)向导生成的代码。但结果是相同的,即释放线程以使其能够执行其他进程。

    ASMX 处理程序调用服务器的 BeginXXX 函数后,会将线程返回到进程线程池,使之能够处理接收到的任何其他请求。但是,还不能释放请求的 HttpContext。ASMX 处理程序将等待,直到它传递给 BeginXXX 函数的回调函数被调用,它才结束处理请求。

    一旦回调函数被调用,ASMX 处理程序将调用 EndXXX 函数,使您的 Web 方法可以完成任何所要执行的处理,并且可以得到被序列化到 SOAP 响应中的返回数据。EndXXX 函数返回后将发送响应,只有此时该请求的 HttpContext 才得到释放。

    简单的异步 Web 方法

    为举例说明异步 Web 方法,我从一个名为 LengthyProcedure 的简单同步 Web 方法开始,其代码如下所示。然后我们再看一看如何异步完成相同的任务。LengthyProcedure 只占用给定的毫秒数。

    [WebService]
    public class SyncWebService : System.Web.Services.WebService
    {
        [WebMethod]
        public string LengthyProcedure(int milliseconds) 
        { 
            System.Threading.Thread.Sleep(milliseconds);
            return "成功"; 
        }
    }
    

    现在我们将 LengthyProcedure 转换为异步 Web 方法。我们必须创建如前所述的 BeginLengthyProcedure 函数和 EndLengthyProcedure 函数。请记住,我们的 BeginLengthyProcedure 调用需要返回一个 IAsyncResult 接口。这里,我打算使用一个委托以及该委托上的 BeginInvoke 方法,让我们的 BeginLengthyProcedure 调用进行异步方法调用。传递到 BeginLengthyProcedure 的回调函数将被传递到委托上的 BeginInvoke 方法,从 BeginInvoke 返回的 IAsyncResult 将被 BeginLengthyProcedure 方法返回。

    当委托完成时,将调用 EndLengthyProcedure 方法。我们将调用委托上的 EndInvoke 方法,以传入 IAsyncResult,并将其作为 EndLengthyProcedure 调用的输入。返回的字符串将是从该 Web 方法返回的字符串。下面是其代码:

    [WebService]
    public class AsyncWebService : System.Web.Services.WebService
    {
        public delegate string LengthyProcedureAsyncStub(
            int milliseconds);
    
        public string LengthyProcedure(int milliseconds) 
        { 
            System.Threading.Thread.Sleep(milliseconds);
            return "成功"; 
        }
    
        public class MyState 
        { 
            public object previousState; 
            public LengthyProcedureAsyncStub asyncStub; 
        }
    
        [ System.Web.Services.WebMethod ]
        public IAsyncResult BeginLengthyProcedure(int milliseconds, 
            AsyncCallback cb, object s)
        {
            LengthyProcedureAsyncStub stub 
                = new LengthyProcedureAsyncStub(LengthyProcedure);
            MyState ms = new MyState();
            ms.previousState = s; 
            ms.asyncStub = stub;
            return stub.BeginInvoke(milliseconds, cb, ms);
        }
      
        [ System.Web.Services.WebMethod ]
        public string EndLengthyProcedure(IAsyncResult call)
        {
            MyState ms = (MyState)call.AsyncState;
            return ms.asyncStub.EndInvoke(call);
        }
    }
    

    何时采用异步 Web 方法

    在确定是否适合在您的应用程序中采用异步 Web 方法时,有几个问题需要考虑。首先,调用的 BeginXXX 函数必须返回一个 IAsyncResult 接口。IAsyncResult 是从多个异步 I/O 操作返回的,这些操作包括访问数据流、进行 Microsoft® Windows® 套接字调用、执行文件 I/O、与其他硬件设备交互、调用异步方法,当然也包括调用其他 Web 服务。您可以从这些异步操作中得到 IAsyncResult,以便从 BeginXXX 函数返回它。您也可以创建自己的类以实现 IAsyncResult 接口,但随后可能需要以某种方式包装前面提到的某个 I/O 操作。

    对于前面提到的大多数异步操作,使用异步 Web 方法包装后端异步调用很有意义,可以使 Web 服务代码更有效。但使用委托进行异步方法调用时除外。委托会导致异步方法调用占用进程线程池中的某个线程。不幸的是,ASMX 处理程序为进入的请求提供服务时同样要使用这些线程。所以与对硬件或网络资源执行真正 I/O 操作的调用不同,使用委托的异步方法调用在执行时仍将占用其中一个进程线程。您也可以占用原来的线程,同步运行您的 Web 方法。

    下面的示例显示了一个调用后端 Web 服务的异步 Web 方法。它已经使用 WebMethod 属性标识了 BeginGetAgeEndGetAge 方法,以便异步运行。此异步 Web 方法的代码调用名为 UserInfoQuery 的后端 Web 方法,以获得它需要返回的信息。对 UserInfoQuery 的调用被异步执行,并被传递到 AsyncCallback 函数,后者被传递到 BeginGetAge 方法。这将导致当后端请求完成时,调用内部回调函数。然后,回调函数将调用 EndGetAge 方法以完成请求。此示例中的代码比前面示例中的代码简单得多,并且还具有另外一个优点,即没有在与为中间层 Web 方法请求提供服务的相同线程池中启动后端处理。

    [WebService]
    public class GetMyInfo : System.Web.Services.WebService
    {
        [WebMethod]
        public IAsyncResult BeginGetAge(AsyncCallback cb, Object state)
        {
            // 调用异步 Web 服务调用。
            localhost.UserInfoQuery proxy 
                = new localhost.UserInfoQuery();
            return proxy.BeginGetUserInfo("用户名", 
                                          cb, 
                                          proxy);
        }
    
        [WebMethod]
        public int EndGetAge(IAsyncResult res)
        {
            localhost.UserInfoQuery proxy 
                = (localhost.UserInfoQuery)res.AsyncState;
            int age = proxy.EndGetUserInfo(res).age;
            //  在此对 Web 服务的结果进行其他
            //  处理。
            return age;
        }
    }
    

    发生在 Web 方法中的最常见的 I/O 操作类型之一是对 SQL 数据库的调用。不幸的是,目前 Microsoft® ADO.NET 尚未定义一个完好的异步调用机制;而只是将 SQL 调用包装到异步委托调用中对提高效率没有什么帮助。虽然有时可以选择缓存结果,但是也应当考虑使用 Microsoft SQL Server 2000 Web Services Toolkit(英文)将您的数据库发布为 Web 服务。这样您就可以利用 .NET Framework 中的支持,异步调用 Web 服务以查询或更新数据库。

    通过 Web 服务调用访问 SQL 时,需要注意众多的后端资源。如果您使用了 TCP 套接字与 Unix 计算机通信,或者通过专用的数据库驱动程序访问其他一些可用的 SQL 平台,甚至具有使用 DCOM 访问的资源,您都可以考虑使用众多的 Web 服务工具包将这些资源发布为 Web 服务。

    使用这种方法的优点之一是您可以利用客户端 Web 服务结构的优势,例如使用 .NET Framework 的异步 Web 服务调用。这样您将免费获得异步调用能力,而您的客户端访问机制会与异步 Web 方法高效率地配合工作。

    使用异步 Web 方法聚合数据

    现在,许多 Web 服务都访问后端的多个资源并为前端的 Web 服务聚合信息。尽管调用多个后端资源会增加异步 Web 方法模型的复杂性,但最终还是能够显著提高效率。

    假设您的 Web 方法调用两个后端 Web 服务:服务 A 和服务 B。从您的 BeginXXX 函数,您可以异步调用服务 A 和服务 B。您应该向每个异步调用传递自己的回调函数。在从服务 A 和服务 B 接收到结果后,为触发 Web 方法的完成,您提供的回调函数将验证所有的请求都已完成,在返回的数据上进行所有的处理,然后调用传递到 BeginXXX 函数的回调函数。这将触发对 EndXXX 函数的调用,此函数的返回将导致异步 Web 方法的完成。

    小结

    异步 Web 方法在 ASP.NET Web 服务中提供了一个有效的机制,可以调用后端服务,而不会导致占用却不利用进程线程池中的宝贵线程。通过结合对后端资源的异步请求,服务器可以使用自己的 Web 方法使同时处理的请求数目达到最大。您应该考虑使用此方法开发高性能的 Web 服务应用程序。

    展开全文
  • 同步VS异步

    千次阅读 2015-02-12 11:12:08
    同步VS异步Boost.Asio的作者做了一个很惊艳的工作:它可以让你在同步和异步中自由选择,从而更好地适应你的应用。在之前的章节中,我们已经学习了各种类型应用的框架,比如同步客户端,同步服务端,异步客户端,异步...
  • 最近朋友建议我写一些... 该程序可以在公共网络上运行,只要输入服务器的IP地址即可。  程序不是很难,由于时间过了一年多了,现在也不好详细讲解了。就贴一下代码,程序还是很容易理解的,看英文单词就知道代码的
  • Q:什么是同步逻辑和异步逻辑? A:同步逻辑是时钟之间有固定的因果关系;... 异步电路:电路中没有统一的时钟,有些触发器的时钟输入端与时钟脉冲源相连,这些触发器的状态变化与时钟脉冲同步,...
  • 服务器端异步 Web 方法(一)

    千次阅读 2004-04-23 13:26:00
    服务器端异步 Web 方法 Matt PowellMicrosoft Corporation 2002年10月2日 摘要:Matt Powell 介绍了如何在服务器使用异步 Web 方法,来创建高性能的 Microsoft ASP.NET Web 服务。 简介在九月份的第三篇专栏(英文...
  • 服务器端异步 Web 方法(二)

    千次阅读 2004-04-23 13:31:00
    简单的异步 Web 方法为举例说明异步 Web 方法,我从一个名为 LengthyProcedure 的简单同步 Web 方法开始,其代码如下所示。然后我们再看一看如何异步完成相同的任务。LengthyProcedure 只占用给定的毫秒数。...
  • 异步下载照片墙

    千次阅读 2016-06-28 19:57:28
    android异步下载照片墙
  • 寄存器电路的Verilog描述方式一、最基本的寄存器二、 异步复位寄存器三、异步置位寄存器四...功能:在clk时钟信号的上升沿,输入端数据din被锁存到输出端dout。 Verilog代码: moudle dff(clk,din,dout) input cl...
  • 同步异步3:TDMA中的同步异步

    千次阅读 2016-02-20 21:19:56
    在TDMA中也出现过同步和异步的概念,前者同步的时隙和发送划分比较死板,适合一些固定流量类型的发送,比如传统的话网,所有人的数据包大小和类型都是相同的,而后者适合一些灵活的环境,一般情况下,貌似异步TDMA也...
  • javascript异步编程

    千次阅读 2015-06-27 07:23:43
    异步机制JavaScript的执行环境是单线程的,单线程的好处是执行环境...所以在浏览器,耗时很长的操作都应该异步执行,避免浏览器失去响应。所谓异步执行,不同于同步执行(程序的执行顺序与任务的排列顺序是一致的、
  • 异步串行通信

    千次阅读 2019-01-28 11:45:11
    异步串行通信
  • C 异步调用

    千次阅读 2019-02-07 09:23:47
    C 异步调用
  • Java异步socket

    千次阅读 2010-06-23 11:20:00
    异步输入输出流编写Socket进程通信程序 在Merlin中加入了用于实现异步输入输出机制的应用程序接口包:java.nio(新的输入输出包,定义了很多基本类型缓冲(Buffer)),java.nio.channels(通道及选择器...
  • Linux设备驱动中的异步通知和异步IO

    千次阅读 2016-11-10 23:50:53
    异步通知和异步IO
  • 异步通信还要设置波特率?_深入理解同步/异步通信   上一篇我们解释了串口通信中同步通信和异步通信的区别,详见上篇链接。其中我们分析同步/异步通信最重要的不同点就是是否同步时钟,可能就有很多小伙伴不理解,...
  • 同步置数与异步置数

    万次阅读 2016-07-20 15:51:23
    集成计数器的置数方式有异步和同步两种。  异步置数:与时钟脉冲CP...同步置数:输入端获得置数信号后,只是为置数创造了条件,还需要再输入一个计数脉冲CP,计数器才能将预置数置入。 收藏于 2008-12-15
  • 同步异步复位分析

    千次阅读 2019-07-10 20:39:27
    【Verilog】 同步复位和异步复位比较 同步复位sync 异步复位async 特点 复位信号只有在时钟上升沿到来时才能有效。 无论时钟沿是否到来,只要复位信号...
  • ajax异步调用

    千次阅读 2017-12-22 01:20:46
    ajax 的全称是AsynchronousJavaScript and XML,其中,Asynchronous 是异步的意思,它有别于传统web开发中采用的同步的方式。 2、同步和异步 异步传输是面向字符的传输,它的单位是字符;而同步传输是面向比特的...
  • 同步传输与异步传输

    千次阅读 2019-11-18 15:01:47
    异步传输相比,传输大量数据更加有效和可靠。 异步传输 在异步传输中,数据以字节或字符的形式发送。该传输是半双工型传输。在该传输中,在数据的起始位和停止位都添加了奇偶校验位。它不需要同步。 同步...
  • 异步FIFO设计与实现

    千次阅读 2017-06-22 20:07:02
     异步FIFO是一种先进先出电路,用在需要实时数据接口的部分,用来存储、缓冲在两个异步时钟之间的...异步FIFO与同步FIFO最大的不同在于异步FIFO读写时钟不同,通常异步FIFO用来做数据的时钟域转换,FIFO设计中难度最
  • 异步串口

    千次阅读 2013-12-06 22:34:05
    常用方法是:当接收输入缓冲区内数据量超过设定的高位时,就向数据发送发出xoff字符(十进制的19或control-s,设备编程说明书应该有详细阐述),发送收到 xoff字符后就立即停止发送数据;当接收输入缓冲...
  • UDP异步通信C#

    千次阅读 2014-04-15 15:27:22
    C# 编写的简单UDP异步通信程序(控制台) 客户端发送请求,服务器响应机制 1. [代码]UDP客户端代码  01 using System; 02 using System.Text; 03 ...
  • java异步socket调用

    千次阅读 2008-05-07 17:49:00
    代码号为”Merlin”的J2SE1.4带来了一些激动人心的新特性,诸如对正则表达式的支持,异步输入输出流,通道(Channel),字符集等.虽然该版本还处在测试阶段,但这些新特性早已让开发人员们跃跃欲试.在Merlin发布之前,异步...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 106,559
精华内容 42,623
关键字:

异步输入端