精华内容
下载资源
问答
  • C#回调函数示例

    2017-03-15 22:55:14
    C#回调函数示例 + VS2013 代码
  • C#回调函数

    2018-09-30 15:33:23
    c#回调函数,十分清晰简单易懂
  • 回调函数的目的? 这还要说,当然肯定会完成某项功能了啊。(汗) 回调函数的实现? 上文也提到了,被回调的函数其实是作为参数传递给要执行的函数的。那如何才能将函数作为参数呢?当然是使用委托了,委托的知识...

    C# 回调函数的实现?

    被回调的函数其实是作为参数传递给要执行的函数的。那如何才能将函数作为参数呢?当然是使用委托了,委托的知识这里就不讲解了。
    这样的话我们就很好理解了,那我们就开始实现起来。首先定义一个委托:
    delegate void DelegateDone(); //定义一个无返回值的委托
    再定义一个实现函数,将委托作为参数传递进来:
    void DoWork(DelegateDone callBack){ callBack(); }
    看看是不是就实现了一个简单的回调函数了啊。
    现在我们再回头来看看,是不是必须在函数入参的时候传递进去呢?那当然不是,那上面只是为了便于我们理解回调函数的实现。下面我就我工作中遇到的回调函数使用给大家做一个参考:

    public delegate void GetHeartDataDelegate(HeartModel model); 
    //定义一个委托
    public GetHeartDataDelegate GetHeartHandler; 
    
    //MQTT接收数据处理
    
    void MQTTReceiver(object sender, MqttMsgPublishEventArgs e)
    { 
    	string receiveData = Encoding.Default.GetString(e.Message);
    	if(null != GetHeartHandler)
    	{ //省略转换 
    		GetHeartHandler(receiverData); //调用委托函数 
     	}
    }
    

    //外部调用

    void GetHeartDataCallback(HeartModel model)
    { 
    	//省略实现代码
    }
    void Main()
    {
    	GetHeartHandler=new GetHeartDataDelegate (GetHeartDataCallback); 
    	//绑定需要回调的函数 
    } 
    

    看代码其实很简单,就是在底层我们检测到了数据的传入,回调给上层具体的函数实现。
    总结
    回调函数其实就是把某个方法当做参数传递给另外一个方法。在实际工作中,底层数据接收的回调,订单支付的回调等等都是基于这个思想实现的。

    回调函数的应用场景

    一切要从这样的需求说起

    假设你们公司要开发下一代国民App“明日油条”,一款主打解决国民早餐问题的App。为了加快开发进度,这款应用由A小组和B小组协同开发
    其中有一个核心模块由B小组开发然后供A小组调用,这个核心模块被封装成了一个函数,这个函数就叫make_youtiao()。

    如果make_youtiao()这个函数执行的很快并可以立即返回,那么A小组的同学只需要
    1.调用make_youtiao()
    2.等待该函数执行完成
    3.该函数执行完后继续后续流程
    从程序执行的角度看这个过程是这样的
    1.保存当前被执行函数的上下文
    2.开始执行make_youtiao()这个函数
    3.make_youtiao()执行完后,控制转回到调用函数中
    在这里插入图片描述
    如果世界上所有的函数都像make_youtiao()这么简单,那么程序员大概率就要失业了,还好程序的世界是复杂的,这样程序员才有了存在的价值。

    现实情况并不容易

    现实中make_youtiao()这个函数需要处理的数据非常庞大,假设有10000个,那么make_youtiao(10000)不会立刻返回,而是可能需要10分钟才执行完成并返回。

    这时你该怎么办呢?想一想这个问题。

    可能有的同学就像把头埋在沙子里的鸵鸟一样:和刚才一样直接调用不可以吗,这样多简单。

    是的,这样做没有问题,但就像爱因斯坦说的那样“一切都应该尽可能简单,但是不能过于简单”。

    想一想直接调用会有什么问题?

    显然直接调用的话,那么调用线程会被阻塞暂停,在等待10分钟后才能继续运行。在这10分钟内该线程不会被操作系统分配CPU,也就是说该线程得不到任何推进。

    这并不是一种高效的做法。

    没有一个程序员想死盯着屏幕10分钟后才能得到结果。

    那么有没有一种更加高效的做法呢?

    想一想我们上一篇中那个一直盯着你写代码的老板.我们已经知道了这种一直等待直到另一个任务完成的模式叫做同步。
    如果你是老板的话你会什么都不干一直盯着员工写代码吗?因此一种更好的做法是程序员在代码的时候老板该干啥干啥,程序员写完后自然会通知老板,这样老板和程序员都不需要相互等待,这种模式被称为异步。回到我们的主题,这里一种更好的方式是调用make_youtiao()这个函数后不再等待这个函数执行完成,而是直接返回继续后续流程,这样A小组的程序就可以和make_youtiao()这个函数同时进行了,就像这样:
    在这里插入图片描述
    在这种情况下,回调(callback)就必须出场了。

    为什么我们需要回调callback

    有的同学可能还没有明白为什么在这种情况下需要回调,别着急,我们慢慢讲。
    假设我们“明日油条”App代码第一版是这样写的:

    make_youtiao(10000);
    sell();
    

    可以看到这是最简单的写法,意思很简单,制作好油条后卖出去。

    在这里插入图片描述
    我们已经知道了由于make_youtiao(10000)这个函数10分钟才能返回,你不想一直死盯着屏幕10分钟等待结果,那么一种更好的方法是让make_youtiao()这个函数知道制作完油条后该干什么,即,更好的调用make_youtiao的方式是这样的:“制作10000个油条,炸好后卖出去”,因此调用make_youtiao就变出这样了:

    make_youtiao(10000, sell);
    

    看到了吧,现在make_youtiao这个函数多了一个参数,除了指定制作油条的数量外还可以指定制作好后该干什么,第二个被make_youtiao这个函数调用的函数就叫回调,callback。

    现在你应该看出来了吧,虽然sell函数是你定义的,但是这个函数却是被其它模块调用执行的,就像这样:

    在这里插入图片描述
    make_youtiao这个函数是怎么实现的呢,很简单:

    void make_youtiao(int num, func call_back) {
     // 制作油条
        call_back(); //执行回调 
    }  
    

    这样你就不用死盯着屏幕了,因为你把make_youtiao这个函数执行完后该做的任务交代给make_youtiao这个函数了,该函数制作完油条后知道该干些什么,这样就解放了你的程序。
    为什么要用回调?这里是根据业务场景用回调(同步调用方式:A小组调用B小组make_youtiao函数以后A小组再sell卖出去。改成同步回调方式:A小组调用B小组make_youtiao函数并委托B小组制作油条以后B小组再sell卖出去),但是对于程序没有性能提升,感觉要用回调的理由不是很充分。
    如果改成异步回调(A小组委托B小组make_youtiao以后再B小组sell卖出去同时A小组不等待B小组,可以去做其他事情)。对程序有性能提升,这里用回调的理由很充分。

    有的同学可能还是有疑问,
    为什么编写make_youtiao这个小组不直接定义sell函数然后调用呢?
    不要忘了明日油条这个App是由A小组和B小组同时开发的,B小组在编写make_youtiao时怎么知道A小组要怎么用这个模块,假设B小组真的自己定义sell函数就会这样写:

    void make_youtiao(int num) {
      real_make_youtiao(num);
        sell(); //执行回调 
    }
    

    同时B小组设计的模块非常好用,这时C小组也想用这个模块,然而C小组的需求是制作完油条后放到仓库而不是不是直接卖掉,要满足这一需求那么B小组该怎么写呢?

    void make_youtiao(int num) {
    real_make_youtiao(num);
    if (Team_B) {
           sell(); // 执行回调
    } else if (Team_D) {
           store(); // 放到仓库
    }
    

    故事还没完,假设这时D小组又想使用呢,难道还要接着添加if else吗?这个问题该怎么解决呢?关于这个问题的答案,你懂的。

    正式定义

    在计算机科学中,回调函数是指一段以参数的形式传递给其它代码的可执行代码。
    这就是回调函数的定义了。
    注意,回调函数是一种软件设计上的概念,和某个编程语言没有关系,几乎所有的编程语言都能实现回调函数。
    对于一般的函数来说,我们自己编写的函数会在自己的程序内部调用,也就是说函数的编写方是我们自己,调用方也是我们自己。

    但回调函数不是这样的,虽然函数编写方是我们自己,但是函数调用方不是我们,而是我们引用的其它模块,也就是第三方库,我们调用第三方库中的函数,并把回调函数传递给第三方库,第三方库中的函数调用我们编写的回调函数,如图所示:
    在这里插入图片描述而之所以需要给第三方库指定回调函数,是因为第三方库的编写者并不清楚在某些特定节点,比如我们举的例子油条制作完成、接收到网络数据、文件读取完成等之后该做什么,这些只有库的使用方才知道,因此第三方库的编写者无法针对具体的实现来写代码,而只能对外提供一个回调函数,库的使用方来实现该函数,第三方库在特定的节点调用该回调函数就可以了。
    另一点值得注意的是,从图中我们可以看出回调函数和我们的主程序位于同一层中,我们只负责编写该回调函数,但并不是我们来调用的。
    最后值得注意的一点就是回调函数被调用的时间节点,回调函数只在某些特定的节点被调用,就像上面说的油条制作完成、接收到网络数据、文件读取完成等,这些都是事件,也就是event,本质上我们编写的回调函数就是用来处理event的,因此从这个角度看回调函数不过就是eventhandler,因此回调函数天然适用于事件驱动编程event-driven,我们将会在后续文章中再次回到这一主题。

    同步回调

    这种回调就是通常所说的同步回调synchronous callbacks、也有的将其称为阻塞式回调blocking callbacks,或者什么修饰都没有,就是回调,callback,这是我们最为熟悉的回调方式。

    当我们调用某个函数A并以参数的形式传入回调函数后,在A返回之前回调函数会被执行,也就是说我们的主程序会等待回调函数执行完成,这就是所谓的同步回调。

    在这里插入图片描述
    有同步回调就有异步回调。

    回调对应的编程思维模式

    让我们用简单的几句话来总结一下回调下与常规编程思维模式的不同。
    假设我们想处理某项任务,这项任务需要依赖某项服务S,我们可以将任务的处理分为两部分,调用服务S前的部分PA,和调用服务S后的部分PB。
    在常规模式下,PA和PB都是服务调用方来执行的,也就是我们自己来执行PA部分,等待服务S返回后再执行PB部分。

    但在回调这种方式下就不一样了。

    在这种情况下,我们自己来执行PA部分,然后告诉服务S:“等你完成服务后执行PB部分”。

    因此我们可以看到,现在一项任务是由不同的模块来协作完成的。

    即:

    常规模式:调用完S服务后后我去执行X任务,
    回调模式:调用完S服务后你接着再去执行X任务,

    其中X是服务调用方制定的,区别在于谁来执行。

    为什么异步回调这种思维模式正变得的越来越重要
    在同步模式下,服务调用方会因服务执行而被阻塞暂停执行,这会导致整个线程被阻塞,因此这种编程方式天然不适用于高并发动辄几万几十万的并发连接场景,针对高并发这一场景,异步其实是更加高效的,原因很简单,你不需要在原地等待,因此从而更好的利用机器资源,而回调函数又是异步下不可或缺的一种机制。

    回调地狱,callback hell
    有的同学可能认为有了异步回调这种机制应付起一切高并发场景就可以高枕无忧了。

    实际上在计算机科学中还没有任何一种可以横扫一切包治百病的技术,现在没有,在可预见的将来也不会有,一切都是妥协的结果。

    那么异步回调这种机制有什么问题呢?

    实际上我们已经看到了,异步回调这种机制和程序员最熟悉的同步模式不一样,在可理解性上比不过同步,而如果业务逻辑相对复杂,比如我们处理某项任务时不止需要调用一项服务,而是几项甚至十几项,如果这些服务调用都采用异步回调的方式来处理的话,那么很有可能我们就陷入回调地狱中。

    举个例子,假设处理某项任务我们需要调用四个服务,每一个服务都需要依赖上一个服务的结果,
    如果用同步方式来实现的话可能是这样的:

    a = GetServiceA();
    b = GetServiceB(a);
    c = GetServiceC(b);
    d = GetServiceD(c);
    

    代码很清晰,很容易理解有没有。
    我们知道异步回调的方式会更加高效,那么使用异步回调的方式来写将会是什么样的呢?

    GetServiceA(function(a){
    	GetServiceB(a, function(b){
    		 GetServiceC(b, function(c){
    		 	 GetServiceD(c, function(d) {
     				 ....
                	});
              });
     	 });
     });
    

    我想不需要再强调什么了吧,你觉得这两种写法哪个更容易理解,代码更容易维护呢?
    博主有幸曾经维护过这种类型的代码,不得不说每次增加新功能的时候恨不得自己化为两个分身,一个不得不去重读一边代码;另一个在一旁骂自己为什么当初选择维护这个项目。

    异步回调代码稍不留意就会跌到回调陷阱中,那么有没有一种更好的办法既能结合异步回调的高效又能结合同步编码的简单易读呢?
    幸运的是,答案是肯定的。
    Promise, then, await。

    本人理解:

    执行顺序 : 主程序—库函数----回调函数

    1.主程序为何不主动调用库函数,调用回调函数?

    同步调用改成异步回调节省主程序线程等待的时间。

    2.库函数为何不主动调用回调函数?

    ①因为库函数不知道主程序调用完成以后需要做什么,库函数是不知道如何写回调函数逻辑。

    ②就算库函数知道如何写回调函数逻辑。如果还有其他程序调用库函数,那么库函数内部就会有很多if…else…。
    如下代码所示:

    void make_youtiao(int num)
    {
    	real_make_youtiao(num);
    	if (Team_B) {
           sell(); // 执行回调
    	} else if (Team_D) {
           store(); // 放到仓库
    }
    

    3.业务逻辑层BLL层调用数据访问层DAL,如果某种情况下DAL层需要调用BLL层代码的话,这里可以用回调函数。C#项目互相依赖是不允许的,BLL层依赖于DAL层的话,DAL层是无法再调用BLL层。

    展开全文
  • C# 回调函数详解

    千次阅读 2021-03-10 10:46:13
    回调和回调函数是什么 软件模块之间总是存在着一定的接口,回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口。 对于一般的结构化语言,可以通过回调函数来实现回调。回调函数是一个函数...

    回调和回调函数是什么

    软件模块之间存在着接口,而回调是一种双向调用模式,被调用方在接口被调用时也会调用对方的接口。
    对于一般的结构化语言,可以通过回调函数来实现回调。回调函数是一个函数或过程,是一个由调用方自己实现,供被调用方使用的函数。
    对于C和C++来说,一般通过函数指针实现调用。
    对于C#来讲,声明的委托事件就像一个指针,通过事件变量来调用另外的方法,将该方法作为参数传递给另一个方法。回调函数是一个工作流的一部分,由工作流来决定函数的调用(回调)时机。

    怎么实现?

    通过声明委托来实现回调。
    我们在C#编程经常会遇到事件触发流程,定义这个事件的方法就是回调函数。回调函数实际上就是将某种行为即方法存储下来,在需要的时候进行调用。它通过委托实现,并不一定是事件还是委托变量来调用。
    先看一个典型C#委托声明代码:

    public delegate void EventHandler( object sender , EventArgs e )
    

    其中object sender:表示触发事件的控件对象 ,sender参数用于传递指向事件源对象的引用。使用sender 可以查出触发事件的具体控件。
    EventArgs是包含事件数据的类的基类,用于传递事件的细节,是一些事件附属的信息。

    using System;
    
    namespace 回调函数
    {
        //1.声明关于事件的委托;
        public delegate void AlarmEventHandler(object sender, EventArgs e);
        class Dog
        {
            //2.声明事件;   
            public event AlarmEventHandler Alarm;
    
            //3.编写引发事件的函数;
            public void OnAlarm()
            {
                if (this.Alarm != null)
                {
                    Console.WriteLine("\n汪汪~~~~~~~");
                    this.Alarm(this, new EventArgs());   //发出警报
                }
            }
        }
    
        //事件接收者
        class Host
        {
            //4.编写事件处理程序
            void HostHandleAlarm(object sender, EventArgs e)
            {
                Console.WriteLine("主人: 吓死宝宝!");
            }
    
            //5.注册事件处理程序
            public Host(Dog dog)
            {
                dog.Alarm += new AlarmEventHandler(HostHandleAlarm);
            }
        }
    
        class Thief
        {
            void ThiefHandleAlarm(object sender, EventArgs e)
            {
                Console.WriteLine("小偷: 吓死宝宝!");
            }
            public Thief(Dog dog)
            {
                dog.Alarm += new AlarmEventHandler(ThiefHandleAlarm);
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                Dog dog = new Dog();
                Host host = new Host(dog);
                Thief thief = new Thief(dog);
                //当前时间,从2021年3月9日23:59:50开始计时
                DateTime now = new DateTime(2021, 3, 9, 23, 59, 55);
                DateTime midnight = new DateTime(2021, 3, 10, 0, 0, 0);
    
                //等待午夜的到来
                Console.WriteLine("时间一秒一秒地流逝... ");
                while (now < midnight)
                {
                    Console.WriteLine("当前时间: " + now);
                    System.Threading.Thread.Sleep(1000);    //程序暂停一秒
                    now = now.AddSeconds(1);                //时间增加一秒
                }
                Console.WriteLine("\n月黑风高的午夜: " + now);
                Console.WriteLine("小偷悄悄地摸进了女主人的屋内... ");
                dog.OnAlarm();
                Console.ReadLine();
            }
        }
    }
    

    参考文章:
    理解C#回调函数
    C# (事件触发)回调函数,完美处理各类疑难杂症!

    展开全文
  • 使用场景举例 假设有一产品P需要A工厂和B工厂合作完成。 A厂负责包装以及喷绘,B厂负责生产,生产工作由A发起。...于是这里回调函数就上场了. public class A { public DateTime ProductionDate { get; set; }.
    • 使用场景举例
      假设有一产品P需要A工厂和B工厂合作完成。
      A厂负责包装以及喷绘,B厂负责生产,生产工作由A发起。
      现在A工厂定义了几个参数:生产日期,保质期,营养成分,配料等标签。但是A厂不知道具体B厂生产P的具体时间以及营养成分、保质期等参数。
      A厂需要B厂在完成P生产后即时反馈A,以便于A厂进行包装喷绘等工作。
      于是这里回调函数就上场了.
      首先定义类A,包含生产日期属性ProductionDate ,保质期属性ProductionDate ,以及喷绘方法PrintDate。
      定义类B,这里需要用到委托(委托我们这里不过多介绍,不太明白的同学可以自行了解下),用来指向函数,定义带两个参数的委托SetDate(DateTime dt1, DateTime dt2)。
      用法如下:
    public class A
            {
                public DateTime ProductionDate { get; set; }
                public DateTime ProductionDate { get; set; }
                //回调函数
                private void PrintDate(DateTime dt1, DateTime dt2)
                {
                    //dosomething...;
                }
                //调用B CreatingProducts
                private A()
                {
                    B b = new B();
                    //传入回调函数以及参数
                    b.CreatingProducts(ProductionDate, QualityDate, PrintDate);
                }
            }
            public class B
            {
                public delegate void SetDate(DateTime dt1, DateTime dt2);
                public void CreatingProducts(DateTime productionDate, DateTime qualityDate, SetDate setDate)
                {
                    //dosomething...;
                    productionDate = "赋值";
                    productionDate = "赋值";
                    //回调实现
                    setDate(productionDate, qualityDate);
                }
            }
    

    这里的PrintDate()即为回调函数。通常来说B厂都是封装起来的, 只提供接口。只要在A厂里调用B厂的CreatingProducts方法即可得到响应,从而返过来触发A厂的PrintDate来完成打印包装等动作,至此回调函数的作用就明白啦。

    展开全文
  • 本博客一直以来的宗旨就是:用最简单的方式讲清楚不复杂的问题。 因为本人也很菜所以也没法讲太复杂...这篇文章的目的就是讲清楚C#回调函数是什么,以及什么时候使用。 直接拿例子来讲算了- -   using Sy...

    本博客一直以来的宗旨就是:用最简单的方式讲清楚不复杂的问题。

    因为本人也很菜所以也没法讲太复杂HHHHHH......

    所以如果哪天某个大神看到了觉得讲的有问题欢迎指出。

    话不多说进入正题。。

    ——————————————————————————————————————

    这篇文章的目的就是讲清楚C#回调函数是什么,以及什么时候使用

    直接拿例子来讲算了- -

     

    using System;
    
    namespace CallBackTest
    {
        class Program //用户层,执行输入等操作
        {
            static void Main(string[] args)
            {
                
                CalculateClass cc = new CalculateClass();
                FunctionClass fc = new FunctionClass();
    
                int result1 = cc.PrintAndCalculate(2, 3, fc.GetSum);
                Console.WriteLine("调用了开发人员的加法函数,处理后返回结果:" + result1);
    
                int result2 = cc.PrintAndCalculate(2, 3, fc.GetMulti);
                Console.WriteLine("调用了开发人员的乘法函数,处理后返回结果:" + result2);
    
                Console.ReadKey();
            }
    
            
        }
    
        class FunctionClass   //开发层处理,开发人员编写具体的计算方法
        {
            public int GetSum(int a, int b)
            {
                return (a + b);
            }
            public int GetMulti(int a, int b)
            {
                return (a * b);
            }
        }
    
        #region 实际开发中,下面这个类会封装起来,只提供函数接口。相当于系统底层
        class CalculateClass 
        {
            public delegate int SomeCalculateWay(int num1, int num2);
    
            //将传入参数在系统底层进行某种处理,具体计算方法由开发者开发,函数仅提供执行计算方法后的返回值
            public int PrintAndCalculate(int num1 , int num2 , SomeCalculateWay cal) 
            {
                Console.WriteLine("系统底层处理:" + num1);
                Console.WriteLine("系统底层处理:" + num2);
                return cal(num1, num2);//调用传入函数的一个引用   
            }
            //可以封装更多的业务逻辑方法   
            
        }
        #endregion
    
    }
    

    直接复制进控制台项目即可运行。

     

    运行结果:

     

     

     

    感觉例子还是比较直白的。例子能看懂就不用看下面的了。

     

    下面详细解释一下(包含一些关于封装的意义):

    1、中间的FunctionClass中的GetSum()和GetMulti()两个函数称为回调函数。可以看到整个程序中并没有哪个地方通过类似GetSum(1,2)这种形式调用了该函数,只有将其当作另一个函数的参数来进行调用。如cc.PrintAndCalculate(2, 3, fc.GetSum)。

    下面是百度百科的定义:

    回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

     

    简单来说,就是 public delegate int SomeCalculateWay(int num1, int num2) 这行代码,把 SomeCalculateWay 这几个字符定义成一种类型,什么类型呢?-> 带了两个int参数的函数类型。而PrintAndCalculate()函数的第三个参数是这种类型,GetSum(int,int)也是这种类型,所以GetSum这个函数可以被当做参数传入,并且在打印完两个数字后执行,被称为回调函数。

    自此代码部分解释完毕

     

    有的同学可能会问了,那为什么不直接写int result1 = GetSum(1,2)呢?岂不是更方便?用这个回调函数意义在哪呢?

    这就涉及到封装和实际开发的问题了 ↓

    ________________________________________________________

    我们假想一下这个情况:

    我们的项目是个核武器控制器,假设并没有涉及到回调函数。当用户输入1,2并且执行GetSum(1,2)的时候,这个工程会把1,2写进核武器的发射系数里,比如方向方位等,然后GetSum求得发射距离,之后进行发射。

    看起来也很完美?没什么瑕疵?

     

    不,有没有想过万一哪天操作失误了呢。万一哪天某个人输入错了,把-1,-2输入进去了,现在倒好,本来要打到外面去的导弹打到自己家了,这个损失就是不可估量的了。

     

    你可能又会说了,那让程序员在客户端(用户端)判断一下呗,比如加一句 if(a>0 && b>0) getsum(a,b);

    那你有没想过,万一哪天这个程序员的代码写错了一行呢?或者派了一个像我一样很菜的实习生过来写代码?岂不是又要把导弹打到自己家了吗hhhhhhhh。所以,在实际大型应用中,“把参数写进核武器” 这个操作的代码并不是所有人都能接触到的,只有项目里最核心的工程师经过反复测验才能应用上去的,而且要对这些参数甚至是结果进行必要的判断,并且如果要修改代码也是会经过慎重考量的,因为你一改,相当于整个项目底层都进行了改变,所有调用你函数的人执行效果也都会发生改变。

    以上就是封装的意义。(当然封装还有其他意义这里就不赘述了)

    ______________________________________________________________________

    2、在实际开发中,CalculateClass这个类会被封装起来,比如提供一个dll文件给你,你通过引用dll来调用里面的参数或者函数。一般项目里的大佬/主程都会把这些底层的东西打包进dll,防止误操作使得系统崩溃,也让外界不能轻易访问底层的东西。

    在这个类中,public delegate int SomeCalculateWay(int num1, int num2); 这一语句声明了一个委托,后面定义的SomeCalculateWay cal就代表着cal是一个带有两个int参数的函数。关于委托的例子和应用这里也不多讲了,能理解就好。

     

    3、在用户层的main函数里,用户可以通过输入参数2,3,然后获取一个开发人员的方法比如getsum,然后把这些作为参数,调用底层的函数,再得到想要的效果。这样子不管是用户还是开发人员误操作了,最后都会被底层的函数给判断出来,从而不会执行错误的结果而造成损失。

     

    4、当然封装是回调函数的一种用法,还有一种用法就是在有网络延迟的情况下,可以告诉外界某段代码已经在一定延迟后执行完毕,此时回调函数就作为执行后接下来要进行的操作,更详细的用法后续再进行说明。

     

    说了这么多,感觉讲的还是挺清楚的,适合新手看看。。

    如果哪里有错误也希望大家指出,谢谢。。

    展开全文
  • 主要介绍了C#中通过委托来实现回调函数功能的方法,文中举了一个典型的多线程回调程序实例,需要的朋友可以参考下
  • 一个Demo,描述了C#如何在C++中注册函数回调
  • 主要介绍了C#中异步回调函数用法,实例分析了异步回调函数的定义及使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
  • C# 回调函数 简介

    千次阅读 2014-06-28 01:27:51
    什么是C# 回调函数? C# 回调函数是应用程序提供给Windows系统DLL或其它DLL调用的函数,一般用于截获消息、获取系统信息或处理异步事件。应用程序把回调函数的地址指针告诉DLL,而DLL在适当的时候会调用该函数。回调...
  • 本博客一直以来的宗旨就是:用最简单的方式讲清楚不复杂的问题。 因为本人也很菜所以也没法讲太复杂HHHHHH...这篇文章的目的就是讲清楚C#回调函数是什么,以及什么时候使用。 直接拿例子来讲算了- - using System; nam
  • C#传递回调函数

    2016-10-10 16:11:05
    C#传递回调函数给ATL,由ATL调用触发。
  • C#回调函数委托源码

    2015-04-09 10:03:53
    C# 回调函数委托源码,可直接运行,有助于初学者理解委托和回调。其实回调就是委托的一种用法
  • C# 实现回调函数

    2009-04-23 14:12:33
    C# 实现回调函数C# 实现回调函数C# 实现回调函数C# 实现回调函数C# 实现回调函数
  • c#回调函数

    2011-10-10 22:54:52
    回调函数的认识,和大概理解,大家交流学习
  • C# Csharp 调用 C++的DLL中的回调函数

    热门讨论 2014-03-21 13:50:40
    一个是C++的DLL以及源码 一个是调用他的C#源码 都是VS2010编译测试通过
  • C# 回调函数的实现 菜鸟基础

    千次阅读 2020-05-20 15:06:54
    C# 回调函数 1、什么是回调函数 是将某个实现函数作为另一个函数的参数进行调用。通过函数指针调用的函数,当一个函数的指针(地址)作为参数传递给另一个函数,当这个指针指向的函数就是回调函数回调函数不是由该...
  • C# 回调函数

    2010-12-28 11:15:00
    回调函数是应用程序提供给Windows系统DLL或其它DLL调用的函数,一般用于截获消息、获取系统信息或处理异步事件。应用程序把回调函数的地址指针告诉DLL,而DLL在适当的时候会调用该函数。回调函数必须遵守事先规定好...
  • 详解C#委托,事件与回调函数
  • 浅析c#回调函数用法

    千次阅读 2014-01-06 12:27:47
    最近刚接触到回调函数,网上找了找解释,感觉不是很明白,在项目中看到了回调函数的实际用法,那就是回调函数的提供者并不调用这个函数,而是把这个函数地址作为参数,传递给自己调用的其它方法的参数。所以回调函数...
  • C#回调函数 (赞)

    千次阅读 2017-01-05 15:22:17
    原文出处:... C#回调函数应用示例,形象比喻方法助理解,整理了一个简单的例子来说明回调函数的用法:  namespace CallBackFunction { class Program { static void Main(string
  • C# 回调函数,订阅次数的理解

    千次阅读 2018-08-29 15:10:20
    我就简单的说说我对这个机制的理解,首先需要订阅委托,当触发调用委托,回调函数就会响应被触发的委托。如代码所示: public partial class Form1 : Form { //订阅次数 static int count; ...
  • C#回调函数(Callback/IAsyncResult)

    千次阅读 2020-03-11 13:48:35
    1.什么是回调函数 刚接触这个名词的时候不是很懂,查询了MSDN,上面解释的是**引用在相应异步操作完成时调用的方法。**C#
  • C#中委托就像是一个函数的指针,在程序运行时可以使用他们来调用不同的函数。首先是委托存储了方法名,还有参数列表(方法签名),以及返回的类型: delegate string ProcessDelegate(int i); 在程序中使用委托来...
  • C#委托与C++回调函数处理

    热门讨论 2010-01-30 23:24:50
    告诉你怎么用C#委托处理dll中的回调函数。有几篇文档在里面

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 45,300
精华内容 18,120
关键字:

c#回调函数

c# 订阅
友情链接: 30_外部中断.zip