使用委托实现同步回调与异步回调

使用委托可以执行的一项有用操作是实现回调。回调是传入函数的方法,在函数结束执行时调用该方法。

例如,有一个执行一系列数学操作的函数。在调用该函数时,也向其传递一个回调方法,从而在函数完成其计算工作时,调用回调方法,向用户通知计算结果。

 

同步回调

   首先声明两个方法:

AddTwoNumbers():接受两个整型实参以及一个类型委托

ResultCallback():接受一个字符串,并显示出来。代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DelegateCallBack
{
    class Program
    {
        delegate void CallbackDelegate(string msg);

        static void Main(string[] args)
        {
            //方式一:
            CallbackDelegate result = ResultCallback;
            AddTwoNumbers(5, 3, result);

            //方式二:
            AddTwoNumbers(5, 3, ResultCallback);

            Console.Read();
        }

        static private void AddTwoNumbers(int num1,int num2,CallbackDelegate callback)
        {
            int result = num1 + num2;

            callback(result.ToString());
        }

        static private void ResultCallback(string msg)
        {
            Console.WriteLine(msg);
        }
    }
}

异步回调

回调在异步情况下最有用。前面实例中说明的回调是同步回调,也就是按顺序调用函数。如果AddTwoNumbers方法花费较长时间来执行,则该函数之后的所有的语句将被阻塞。

组织较好的方式是异步调用AddTwoNumbers方法。异步调用函数允许主程序继续执行,而不需要等待该函数返回。

在这种异步模型中,当调用AddTwoNumbers函数时,在其后的语句继续执行。当函数结束时,他调用ResultCallback函数。

下面使用异步回调重写前面的程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;

namespace DelegateCallBack
{
    class Program
    {
        delegate int MethodDelegate(int num1, int num2);

        static void Main(string[] args)
        {

            MethodDelegate result = AddTwoNumbers;

            //引用异步操作完成时调用的方法
            AsyncCallback callback = new AsyncCallback(ResultCallback);

            Console.WriteLine("开始异步调用");

            IAsyncResult iresult = result.BeginInvoke(5, 3, callback, null);

            Console.WriteLine("主程序继续执行");

            Console.Read();
        }

        static private int AddTwoNumbers(int num1,int num2)
        {
            int result = num1 + num2;

            System.Threading.Thread.Sleep(5000);

            return result;
        }

        static private void ResultCallback(IAsyncResult ar)
        {
            MethodDelegate dele = (MethodDelegate)((AsyncResult)ar).AsyncDelegate;

            int result = dele.EndInvoke(ar);

            Console.WriteLine("result={0}",result);
        }
    }
}

程序一运行:

五秒后

现在我们分析下程序,首先我们定义一个委托类型,从而可以指向AddTwoNumbers方法。

接下来,定义一个类型为AsyncCallback的委托。AsyncCallback是引用某个方法的委托,当异步操作完成时调用该方法。

使用result 委托的BeginInvoke()方法异步调用AddTwoNumbers(),并且向该方法传递两个整型以及在该方法结束执行时回调的委托。

BeginInvoke()方法异步调用委托,在调用异步委托之后,下一条语句会继续执行。该方法返回类型为IAsyncResult 的变量,该变量表示异步操作的状态。

在ResultCallback方法中,首先使用AsyncDelegate特性获得指向AddTwoNumbers()方法的委托,该特性返回进行异步调用的委托。接下来,使用EndInvoke()方法会的异步调用的结果,向该方法传递IAsycResult变量。

在使用异步回调时,可以通过在不同的线程中执行程序的不同部分来使程序更快速的响应。

时间: 2024-09-17 13:46:33

使用委托实现同步回调与异步回调的相关文章

艾伟_转载:C# 委托的同步调用和异步调用

委托的Invoke方法用来进行同步调用.同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行. 同步调用的例子: using System;using System.Threading;public delegate int AddHandler(int a, int b);public class Foo {static void Main() { Console.WriteLine("**********SyncInvokeTest**************&

C# 委托的同步调用和异步调用

委托的Invoke方法用来进行同步调用.同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行. 同步调用的例子: using System; using System.Threading; public delegate int AddHandler(int a, int b); public class Foo { static void Main() { Console.WriteLine("**********SyncInvokeTest***********

boost库学习随记六:使用同步定时器、异步定时器、bind、成员函数回调处理、多线程的同步处理示例等

一.使用同步定时器 这个示例程序通过展示如何在一个定时器执行一个阻塞等待.       [cpp] view plaincopy   //makefile   #----------------------------------------------------------   #makefile helloworld测试用例   #   #   #   #   #-----------------------------------------------------------   gg

ASP.NET服务器控件封装-【事件】-1.1【事件回发.异步回调】

最近,正在学习ASP.NET服务器控件封装相关的知识,把自己学到的和大家分 享下. 本次内容的概要如下: 1.事件以及为什么需要事件驱动机制: 2.回发的原理: 3.异步回调的原理: 4.事件回发的实现: 5.异步回调的实现. 了解了本次内容的概要,接下来就分节次说明了. 1.事件以及为什么需要事件驱动机制 在C#语言详解一书中对事件的定义是"事件是一种使对象或类能够提供通知的 成员",在这里换句话 说就是页面中已注册事件的对象能够对用户的操作进行捕获并处理.那么为什么 需要引用事件机

使用生成器展平异步回调结构,JS篇

1. 前言 2012 年的时候,我去详细了解过 Python 的 Tornado 框架中的 gen.py 这套工具,http://www.zouyesheng.com/generator-for-async.html ,因为觉得它用于异步环境的编程中实在太方便了,而且,适用性上几乎没有成本,你的定义部分代码完全不需要因为这套工具而作任何改动,这套工具完全是"使用时"的一种可选形式. 那时我想的就是,如果在遍地是 callback 的 Javascript 中也有这样的东西可用就好了.后

深入浅出: Java回调机制(异步)

什么是回调?今天傻傻地截了张图问了下,然后被陈大牛回答道"就一个回调-".此时千万个草泥马飞奔而过(逃 哈哈,看着源码,享受着这种回调在代码上的作用,真是美哉.不妨总结总结. 一.什么是回调 回调,回调.要先有调用,才有调用者和被调用者之间的回调.所以在百度百科中是这样的: 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用.回调和异步调用. 回调是一种特殊的调用,至于三种方式也有点不同. 1.同步回调,即阻塞,单向. 2.回调,即双向(类似自行车的两个齿轮)

深入探析koa之异步回调处理篇

在上一篇中我们梳理了koa当中中间件的洋葱模型执行原理,并实现了一个可以让洋葱模型自动跑起来的流程管理函数.这一篇,我们再来研究一下koa当中异步回调同步化写法的原理,同样的,我们也会实现一个管理函数,是的我们能够通过同步化的写法来写异步回调函数. 1. 回调金字塔及理想中的解决方案 我们都知道javascript是一门单线程异步非阻塞语言.异步非阻塞当然是它的一个优点,但大量的异步操作必然涉及大量的回调函数,特别是当异步嵌套的时候,就会出现回调金字塔的问题,使得代码的可读性非常差.比如下面一个

node.js学习笔记(6) 异步回调

先来看一下国王的幸福生活: 在nodejs王国,国王有很多仆人. 早上,一个仆人叫醒了国王,问他有什么需要. 国王给他一份清单,上面列举了所有需要完成的任务,然后睡回笼觉去了. 当国王回去睡觉之后,仆人才离开国王,拿着清单,给其它的仆人一个个布置任务. 仆人们各自忙各自的去了,直到完成了自己的任务后,才回来把结果禀告给国王. 国王一次只召见一个人,其它的人就在外面排着队等着. 国王处理完这个结果后,可能给他布置一个新的任务,或者就直接让他走了,然后再召见下一个人. 等所有的结果都处理完了,国王就

使用生成器展平异步回调结构

1. 关于异步回调 异步机制,从某个角度,可以看成是--使用非阻塞的流程,以注册回调函数的形式进行业务处理.传统机制,是顺序执行代码,如果某个函数很长时间不返回,那么下面的代码就得不到执行,这就比较浪费时间.然后,对于这种问题的解决,一般有两种办法.一是以线程或进程的方式,跑多个实例,这样来把等待的消耗降低.二是就让函数尽快返回,需要等待的资源得到后再使用另外的函数去处理它. 比如下面的代码: response = fetch('http://zouyesheng.com') s = 1 + 1