委托回调是刚接触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. android 关于插件包内的依赖版本不一致问题得解决

    前言 今天使用一个插件包的时候,依赖包冲突了,在此记录一下. 正文 在引用一个: debugImplementation 'com.squareup.leakcanary:leakcanary-and ...

  2. IIS 部署到服务器上出现数据库连接失败

    前言 以前遇到过本地运行没有任何问题,部署到服务器上却出现数据库连接失败. 正文 排查顺序: 数据库权限 我们的sql的账号决定了我们的权限,那么要观察下是否我们的账号有该数据库的读写权限,先把权限归 ...

  3. SSM使用自定义ConditionalOnProperty实现按需加载spring bean

    SSM使用自定义ConditionalOnProperty实现按需加载spring bean 背景: 公司提供的系统框架是SSM架构,SSM架构是没有springboot的ConditionalOnP ...

  4. 2024-04-17:用go语言,欢迎各位勇者莅临力扣城,本次的挑战游戏名为「力扣泡泡龙」。 游戏的起点是一颗形状如二叉树的泡泡树,其中每个节点的值代表该泡泡的分值。勇者们有一次机会可以击破一个节点泡

    2024-04-17:用go语言,欢迎各位勇者莅临力扣城,本次的挑战游戏名为「力扣泡泡龙」. 游戏的起点是一颗形状如二叉树的泡泡树,其中每个节点的值代表该泡泡的分值.勇者们有一次机会可以击破一个节点泡 ...

  5. 了解redis的单线程模型工作原理?一篇文章就够了

    1.首先redis是单线程的,为什么redis会是单线程的呢?从redis的性能上进行考虑,单线程避免了上下文频繁切换问题,效率高:从redis的内部结构设计原理进行考虑,redis是基于Reacto ...

  6. dom4j 通用解析器,解析成List<Map<String,Object>>

    import java.io.InputStream; import java.util.Iterator; import java.util.LinkedHashMap; import java.u ...

  7. DC-1渗透靶场实战速通版

    "感谢您阅读本篇博客!如果您觉得本文对您有所帮助或启发,请不吝点赞和分享给更多的朋友.您的支持是我持续创作的动力,也欢迎留言交流,让我们一起探讨技术,共同成长!谢谢!" 文章为速通 ...

  8. 第12課-Mirth生产环境宕机后基于服务配置XML备份恢复之记录

    Mirth Connect作为集成交换平台,生产环境互联互通了众多系统,脑残的是连自家关键业务系统都依托mirth来进行交互,宕机或故障对身处其中的一次紧张的业务系统升级都造成高度的精神紧张:这种宕机 ...

  9. 如何定位并修复 HttpCore5 中的 HTTP2 流量控制问题

    ​简介:开篇吹一波阿里云性能测试服务 PTS,PTS 在 2021 年 5 月份已经上线了对 HTTP2 协议的支持(底层依赖 httpclient5),在压测时会通过与服务端协商的结果来决定使用 H ...

  10. Flink 在顺丰的应用实践

    ​简介: 顺丰基于 Flink 建设实时数仓的思路,引入 Hudi On Flink 加速数仓宽表,以及实时数仓平台化建设的实践. 本⽂由社区志愿者苗文婷整理,内容源⾃顺丰科技大数据平台研发工程师龙逸 ...