委托回调是刚接触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. docker 应用篇————docker-compose[十九]

    前言 简单介绍一下docker compose. 正文 首先进行下载一下. sudo curl -L "https://github.com/docker/compose/releases/ ...

  2. leetcode第 181 场周赛

    5364. 按既定顺序创建目标数组 给你两个整数数组 nums 和 index.你需要按照以下规则创建目标数组: 目标数组 target 最初为空. 按从左到右的顺序依次读取 nums[i] 和 in ...

  3. 不常用的技能-【手动编译java类】

    jdk版本:1.7 冒号分割jar包,1.8 分号分割jar包 javac -classpath fastjson-1.2.24.jar:jedis-2.9.0.jar Test.javajava - ...

  4. 在RockyLinux 9.3环境中采用RPM模式部署Oracle 19C

    在RockyLinux 9.3环境中采用RPM模式部署Oracle 19C 用途 在开发数据库系统时,可以验证功能是否与Oracle的表现一致,验证正确性和兼容性 限制 虚拟机安装,CPU 2*4 内 ...

  5. 力扣1077(MySQL)-项目员工Ⅲ(中等)

    题目: 写 一个 SQL 查询语句,报告在每一个项目中经验最丰富的雇员是谁.如果出现经验年数相同的情况,请报告所有具有最大经验年数的员工. 查询结果格式在以下示例中: employee_id 为 1 ...

  6. 深度 | 从DevOps到BizDevOps, 研发效能提升的系统方法

    ​简介:研发效能提升不知从何下手.一头雾水?阿里资深技术专家一文为你揭秘研发效能提升的系统方法. ​ 注:本文是对云栖大会何勉分享内容的整理 这几年"研发效能"一直是热词,很多组织 ...

  7. 函数计算 GB 镜像秒级启动:下一代软硬件架构协同优化揭秘

    ​简介:本文将介绍借助函数计算下一代 IaaS 底座神龙裸金属和安全容器,进一步降低绝对延迟且能够大幅降低冷启动频率. 作者:修踪 背景 函数计算在 2020 年 8 月创新地提供了容器镜像的函数部署 ...

  8. 探索 WPF 的 ITabletManager.GetTabletCount 在 Win11 系统的底层实现

    本文将和大家介绍专为 WPF 触摸模块提供的 ITabletManager 的 GetTabletCount 方法在 Windows 11 系统的底层实现 本文属于 WPF 触摸相关系列博客,偏系统底 ...

  9. k8s网页访问实战

    流程: 客户端访问--->ingress七层代理---->service四层代理---->deployment 详细情况:https://www.cnblogs.com/yangme ...

  10. OLAP系列之分析型数据库clickhouse权限控制(六)

    一.clickhouse权限管理 users.xml默认配置文件: <?xml version="1.0"?> <clickhouse> <profi ...