委托回调是刚接触c#时最头疼的东西,老看老忘,遂整理一下现在对委托回调的理解。如有错误,请指出,感谢。

委托

C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。

回调函数

回调函数就是允许用户把需要调用的方法的指针作为参数传递给一个函数,以便该函数在处理相似事件的时候可以灵活的使用不同的方法。

注意:定义的回调方法签名必须和委托对象一致,这是因为将方法绑定到委托时,编译器会检测他们的兼容性。不符合的话回报编译错误。就比如有一个方法要传入String类型,我们给它传递了一个int类型一样。

委托回调的作用:

调用时,委托可以调用多个方法。 这被称为多播。 若要向委托的方法列表(调用列表)添加其他方法,只需使用加法运算符或加法赋值运算符(“+”或“+=”)添加两个委托。

回调函数可以把调用者与被调用者分开,所以调用者不关心谁是被调用者以及被调用者如何实现。它只需知道存在一个具有特定原型和限制条件的被调用函数。

代码示例:

public static void add(int a,int b)
{
Console.WriteLine(a + b);
}
public static void multiply(int a,int b)
{
Console.WriteLine(a * b);
}
static void Main(string[] args)
{
int x = 1, y = 3;
add(x, y);
multiply(x, y);
Console.ReadLine();
}

委托版:

//申明委托
public delegate void CalculateDelegate(int a, int b);
public static CalculateDelegate calculateDelegate;
//回调函数1
public static void add(int a,int b)
{
Console.WriteLine(a + b);
}
//回调函数2
public static void multiply(int a,int b)
{
Console.WriteLine(a * b);
}
static void Main(string[] args)
{
int x = 1, y = 3;
calculateDelegate = add;//绑定事件
calculateDelegate += multiply;//多播
calculateDelegate(x, y);
Console.ReadLine();
}

项目代码中遇到的委托回调示例

事件发送者的主要工作就是监听,当监听到某一临界条件成立后,将事件告知事件接收者,由事件接收者完成后续动作。

示例1:窗口间传输数据

我做的标注工具,仿labelimg,在子窗口输入label以后,要传回主窗口。我用的是委托(不太清楚有没有其他好的方法)。

(1)事件发布者:子窗口

//申明事件的委托
public delegate void LabelNameDelegate(string labelName);
public LabelNameDelegate labelNameDelegate; //引发事件的函数
private void btnOK_Click(object sender, EventArgs e)
{
...
if (labelNameDelegate != null)
labelNameDelegate(txtLabelName.Text.Trim());
...
}

(2)事件监听者:主窗口

//绑定事件
form.labelNameDelegate = addLabelToList;
//事件发生后的处理程序
private void addLabelToList(string labelName)
{
listboxLabel.Items.Add(labelName);
...
}

示例2:相机获取图像

在实际工作中,较常接触到的例子是相机的委托回调。相机的代码由相机厂商提供,我们只需调用其中的方法,而不用知道它是如何处理数据的。比如相机都会提供开始捕获的委托,该委托会传回图像数据,我们再对图像数据进行处理,比如直接把它显示在picturebox上。我们要写的是对应的得到图像后的处理函数,比如下面的GetImage,其参数和委托参数相同。最重要的是要将事件绑定,即Camera.Acqfun = GetImage。此时,一旦Camera的开始获取图像事件触发,图像就会传到GetImage函数中,并由其处理,显示在picturebox中。

(1)事件发布者:相机

打开相机,会触发camera类的StartAcq(开始获取图像)事件。事件订阅者利用方法GetImage(从图像数据中获取图片)处理事件。

public class Camera
{
//1. 声明事件的委托
    public delegate void AcqDelegate(IntPtr imgPtr,int imgHeight,int imgWidth);
//2. 声明事件
    public AcqDelegate AcqFun;
//3. 编写引发事件的函数(事件的触发一般在某个函数中)
    public override bool StartAcq()
    {
...
if(AcqFun!=null)
AcqFun();
        ...
    }
}

事件订阅者

public class xxx
{
//4. 编写事件处理程序
public void GetImage(IntPtr imgdata, int imageHeight, int imageWidth)
{
...
}
public void StartCamera(Camera.AcqDelegate acqfun)
{  
    //5. 注册事件处理程序
    camera.AcqFun = acqfun;
    //6. 触发事件
    camera.StartAcq();
}
}

触发事件

 StartCamera(GetImage);

参考:

https://www.cnblogs.com/jiangshuai52511/p/7600472.html

c#笔记(3) 委托回调的更多相关文章

  1. 【转】第5篇:Xilium CefGlue 关于 CLR Object 与 JS 交互类库封装报告:自动注册JS脚本+委托回调方法分析

    作者: 牛A与牛C之间 时间: 2013-11-19 分类: 技术文章 | 暂无评论 | 编辑文章 主页 » 技术文章 » 第5篇:Xilium CefGlue 关于 CLR Object 与 JS ...

  2. 【转】第4篇:Xilium CefGlue 关于 CLR Object 与 JS 交互类库封装报告:委托回调方法分析

    作者: 牛A与牛C之间 时间: 2013-11-18 分类: 技术文章 | 暂无评论 | 编辑文章 主页 » 技术文章 » 第4篇:Xilium CefGlue 关于 CLR Object 与 JS ...

  3. 对“demo!demo.Index+HookProc::Invoke”垃圾收集的类型已委托回调。这可能会导致应用程序崩溃、损坏和数据丢失。当传递委托给非托管代码,托管应用程序必须让这些委托保持活着

    对"demo!demo.Index+HookProc::Invoke"垃圾收集的类型已委托回调.这可能会导致应用程序崩溃.损坏和数据丢失.当传递委托给非托管代码,托管应用程序必须承 ...

  4. 6.26学习 异步委托回调函数 VS 多线程 VS 并行处理

    描述: 我现在是轮询着构建实例,然后这个实例去执行一个方法,但是执行方法需要大约10s时间,全部轮询下来需要很长时间.所以我现在要更改,头给了我两个方法,1多线程 2异步委托回调函数. 异步委托回调函 ...

  5. MOOS学习笔记2——HelloWorld回调

    MOOS学习笔记2--HelloWorld回调 例程 #include "MOOS/libMOOS/Comms/MOOSAsyncCommClient.h" bool OnConn ...

  6. C#跨窗体调用控件(委托回调函数使用例子)

    问题: 有两个窗体,FORM1(含一个label控件,一个名为显示form2的button控件)和FORM2(含一个button控件).启动时,FORM1中点击button控件显示form2使FORM ...

  7. C#委托+回调详解

    今天写不完,明天会接着写的,,,, 学习C#有一段时间了,不过C#的委托+回调才这两天才会用,以前只是知道怎么用.前面的一篇文章,函数指针,其实是为这个做铺垫的,说白了委托就相当于C语言中的函数指针, ...

  8. [Clr via C#读书笔记]Cp17委托

    Cp17委托 简单介绍 delegate回调函数机制,可以理解存储函数地址的变量类型: 类型安全: 引用类型支持逆变和协变: 回调 静态方法,实例方法 委托的本质 所有的委托都派生自System.Mu ...

  9. jQuery笔记之 Ajax回调地狱

    本次演示回调地狱: 模拟电影网站,判断用户是否为该网址的vip用户(最高权限为vip) 如果vpi就展示出vip电影,点击相应的电影显示出该电影的详细介绍 ---------------------- ...

  10. C# 异步委托回调函数使用

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

随机推荐

  1. 力扣29(java)-两数相除(中等)

    题目: 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 整数除 ...

  2. 网易:Flink + Iceberg 数据湖探索与实践

    导读:今天主要和大家交流的是网易在数据湖 Iceberg 的一些思考与实践.从网易在数据仓库建设中遇到的痛点出发,介绍对数据湖 Iceberg 的探索以及实践之路. 主要内容包括: 数据仓库平台建设的 ...

  3. 用手机写代码:基于 Serverless 的在线编程能力探索

    ​简介:Serverless 架构的按量付费模式,可以在保证在线编程功能性能的前提下,进一步降低成本.本文将会以阿里云函数计算为例,通过 Serverless 架构实现一个 Python 语言的在线编 ...

  4. 双11特刊|购物车实时显示到手价,看云原生内存数据库Tair如何提升用户体验?

    ​阿里云自研内存数据库Tair诞生于2009年,是一种支持高并发低延迟访问的云原生内存数据库,完全兼容Redis,已历经多年双11大促考验,提供核心在线访问加速能力,显著提升系统吞吐量. 作为双11大 ...

  5. C# 二进制数组与结构体的互转

    本文将告诉大家在 dotnet 里面的二进制基础处理知识,如何在 C# 里面将结构体数组和二进制数组进行相互转换的简单方法 尽管本文属于基础入门的知识,但是在阅读之前还请自行了解 C# 里面的结构体内 ...

  6. 使用 WPF 做个 PowerPoint 系列 文本 BodyProperties 的 FontScale 与文本字号缩放

    本文来告诉大家,在 OpenXML 的 BodyProperties 的 NormalAutoFit 的 FontScale 属性缩放文本框的文本字号的方法 通过 ECMA 376 文档可以了解到 B ...

  7. Jenkins+Harbor+gogs+docker+portainer+springboot实现devOps(企业实战)

    本篇主要讲述springboot以及vue前后端分离项目,使用Jenkins拉取gogs代码仓库源码,构建Docker镜像并推送至Harbor仓库,使用docker 可视化部署工具[portainer ...

  8. HAL库移植RT-Thread Nano

    一.移植RT-Thread Nano准备 keil软件 CubeMx软件 STM32 CubeMx使用教程:https://www.cnblogs.com/jzcn/p/16313803.html S ...

  9. DE10-Lite加速度计使用教程

    DE10-Lite加速度计使用教程 1. 概述 DE10-Lite实验板上有一片5轴加速度计芯片ADXL345(通常称为G-sensor).它可以用来测量板子的倾斜角度.本文讲述如何以50次/秒的速度 ...

  10. Spire.Doc 生成长图

    按模板生成内容,转换成长图保存: Document doc = new Document("A_BizRpt.docx"); ....... Image[] imgs = doc. ...