通过委托执行多个函数

UE5 C++(十二)— 委托(代理)、多播委托 这个官网上有很详细介绍,这里介绍几个点委托 是一种泛型但类型安全的方式,可在C++对象上调用成员函数。可使用委托动态绑定到任意对象的成员函数,之后在该对象上调用函数,即使调用程序不知对象类型也可进行操作。复制委托对象很安全。你也可以利用值传递委托,但这样操作需要在堆上分配内存,因此通常并不推荐。请尽量通过引用传递委托。 阅读详情


一、通过委托执行多个函数

假设我们在某个场景下需要运行一个逻辑:
关闭破真空-关闭吸真空-打开吸真空-延时200ms-处理其他逻辑-关闭吸真空-打开破真空-延时200ms-关闭破真空
其中每一个的执行都有可能是失败的(比如真空表值异常、通讯失败等原因),失败后就要报警等待人工检查处理而不应该继续往下执行

【以下代码比较长,但都是最简单的模型示例而已,请耐心看完】

我们常规的做法一般是这样:

public bool Run()
{
    bool flag = false;
    flag = CloseBreakVacuum();
    if (!flag)
    {
        return false;
    }
    flag = CloseSuctionVacuum();
    if (!flag)
    {
        return false;
    }
    flag = OpenSuctionVacuum();
    if (!flag)
    {
        return false;
    }
    Delay(200);
    OtherLogic();
    flag = CloseSuctionVacuum();
    if (!flag)
    {
        return false;
    }
    flag = OpenBreakVacuum();
    if (!flag)
    {
        return false;
    }
    Delay(200);
    flag = CloseBreakVacuum();
    if (!flag)
    {
        return false;
    }
    return flag;
}

public bool CloseBreakVacuum()
{
    // TODO..关闭破真空,读真空表气压值判断是否关闭成功
    return true;
}
public bool CloseSuctionVacuum()
{
    // TODO..关闭吸真空,读真空表气压值判断是否关闭成功
    return true;
}
public bool OpenBreakVacuum()
{
    // TODO..打开破真空,释放产品时防止产品黏在吸嘴上,读真空表气压值判断是否成功释放到产品
    return true;
}
public bool OpenSuctionVacuum()
{
    // TODO..打开吸真空,吸取产品,读真空表气压值判断是否成功吸取到产品
    return true;
}
public void Delay(int ms)
{
    // TODO..延时指定时间
}
public void OtherLogic()
{
    // TODO..处理其他逻辑
}

可以看出来这样的可读性太差了,那么如何优化呢?我们可以使用委托的做法:

public bool Run()
{
    bool flag = false;
    foreach (var func in new Func<bool>[] { CloseBreakVacuum, CloseSuctionVacuum, OpenSuctionVacuum })
    {
        flag = func();
        if(!flag)
        {
            return false;
        }
    }

    Delay(200);
    OtherLogic();

    foreach (var func in new Func<bool>[] { CloseSuctionVacuum, OpenBreakVacuum })
    {
        flag = func();
        if (!flag)
        {
            return false;
        }
    }

    Delay(200);

    foreach (var func in new Func<bool>[] { CloseBreakVacuum })
    {
        flag = func();
        if (!flag)
        {
            return false;
        }
    }

    return true;
}

public bool CloseBreakVacuum()
{
    // TODO..关闭破真空,读真空表气压值判断是否关闭成功
    return true;
}
public bool CloseSuctionVacuum()
{
    // TODO..关闭吸真空,读真空表气压值判断是否关闭成功
    return true;
}
public bool OpenBreakVacuum()
{
    // TODO..打开破真空,释放产品时防止产品黏在吸嘴上,读真空表气压值判断是否成功释放到产品
    return true;
}
public bool OpenSuctionVacuum()
{
    // TODO..打开吸真空,吸取产品,读真空表气压值判断是否成功吸取到产品
    return true;
}
public void Delay(int ms)
{
    // TODO..延时指定时间
}
public bool OtherLogic()
{
    // TODO..处理其他逻辑
    return true;
}

这样看,很明显,结构化的代码可读性是不是更加强了

但好处还不止这个,我们再发散下思维,每一步都可能错误,假设是通讯丢包出错,那我们再执行一次是不是就可能成功了?好了,现在欠收拾的产品经理新增了需求,每一步如果重复失败三次(次数需要可以修改)才认为是失败。
那原来的代码可能是这样处理的:

int retryTimes = 3; //重试次数
int errorCount = 0; //失败次数

public bool Run()
{
    bool flag = false;
    errorCount = 0;
    while (errorCount < retryTimes && !flag)
    {
        flag = CloseBreakVacuum();
        errorCount++;
    }
    if (!flag)
    {
        return false;
    }
    errorCount = 0;
    while (errorCount < retryTimes && !flag)
    {
        flag = CloseSuctionVacuum();
        errorCount++;
    }
    if (!flag)
    {
        return false;
    }
    errorCount = 0;
    while (errorCount < retryTimes && !flag)
    {
        flag = OpenSuctionVacuum();
        errorCount++;
    }
    if (!flag)
    {
        return false;
    }

    Delay(200);
    OtherLogic();

    errorCount = 0;
    while (errorCount < retryTimes && !flag)
    {
        flag = CloseSuctionVacuum();
        errorCount++;
    }
    if (!flag)
    {
        return false;
    }
    while (errorCount < retryTimes && !flag)
    {
        flag = OpenBreakVacuum();
        errorCount++;
    }
    if (!flag)
    {
        return false;
    }
    
    Delay(200);

    while (errorCount < retryTimes && !flag)
    {
        flag = CloseBreakVacuum();
        errorCount++;
    }
    if (!flag)
    {
        return false;
    }

    return true;
}

public bool CloseBreakVacuum()
{
    // TODO..关闭破真空,读真空表气压值判断是否关闭成功
    return true;
}
public bool CloseSuctionVacuum()
{
    // TODO..关闭吸真空,读真空表气压值判断是否关闭成功
    return true;
}
public bool OpenBreakVacuum()
{
    // TODO..打开破真空,释放产品时防止产品黏在吸嘴上,读真空表气压值判断是否成功释放到产品
    return true;
}
public bool OpenSuctionVacuum()
{
    // TODO..打开吸真空,吸取产品,读真空表气压值判断是否成功吸取到产品
    return true;
}
public void Delay(int ms)
{
    // TODO..延时指定时间
}
public void OtherLogic()
{
    // TODO..处理其他逻辑
}

而使用委托后可以这样处理:

int retryTimes = 3; //重试次数

public bool Run()
{
    bool flag = false;
    foreach (var func in new Func<bool>[] { CloseBreakVacuum, CloseSuctionVacuum, OpenSuctionVacuum })
    {
        flag = RetryFunc(func, retryTimes);
        if(!flag)
        {
            return false;
        }
    }

    Delay(200);
    OtherLogic();

    foreach (var func in new Func<bool>[] { CloseSuctionVacuum, OpenBreakVacuum })
    {
        flag = RetryFunc(func, retryTimes);
        if (!flag)
        {
            return false;
        }
    }

    Delay(200);

    foreach (var func in new Func<bool>[] { CloseBreakVacuum })
    {
        flag = RetryFunc(func, retryTimes);
        if (!flag)
        {
            return false;
        }
    }

    return true;
}

protected bool RetryFunc(Func<bool> func, int retryTimes = 3)
{
    bool flag = false;
    int errorCount = 0;
    while (errorCount < retryTimes && !flag)
    {
        flag = func();
        errorCount++;
    }
    return flag;
}

public bool CloseBreakVacuum()
{
    // TODO..关闭破真空,读真空表气压值判断是否关闭成功
    return true;
}
public bool CloseSuctionVacuum()
{
    // TODO..关闭吸真空,读真空表气压值判断是否关闭成功
    return true;
}
public bool OpenBreakVacuum()
{
    // TODO..打开破真空,释放产品时防止产品黏在吸嘴上,读真空表气压值判断是否成功释放到产品
    return true;
}
public bool OpenSuctionVacuum()
{
    // TODO..打开吸真空,吸取产品,读真空表气压值判断是否成功吸取到产品
    return true;
}
public void Delay(int ms)
{
    // TODO..延时指定时间
}
public bool OtherLogic()
{
    // TODO..处理其他逻辑
    return true;
}

好了,本文章就到这里了,具体区别,需要自己细细体悟,具体用法,需要举一反三

《Effective C#》Item 21:用委托实现回调 委托属于C#中的新名词,它的应用也非常广泛,例如事件就是委托最简单而又直接的例子。 那么首先说说什么是委托,其实委托在用过C或者C++的人看来就是函数指针,不过使用C#的大多数人都没有用过这两门语言,因此对委托的理解不是很深,对于委托可以简单的从字面去理解,即“委托别人去执行某些操作”,也就是说执行一个操作,而这个操作过程自身并不知道,只是委托过来让你去执行而已。参看如下这个例子。 阅读详情

相关推荐

基于Python的微信聊天记录分析——数据获取

本篇为“基于Python的微信聊天记录分析”第一篇,主要涉及数据获取,包括Python环境配置、WeChatMsg项目配置和运行、获取聊天记录等内容,流程简单、比较基础,后续这个系列会涉及基于Python的数据处理、统计分析、NLP技术等内容。希望和大家多多交流,共同进步!

Henryli1202的博客 1万+

C#中委托的应用与示例

在C#中委托可以分为,命名方法委托、多播委托、匿名委托,其中命名方法委托是最常见的一种委托,在介绍委托的应用时就是命名方法委托。多播委托是指在一个委托中注册多个方法,在注册方法时可以在委托中通过+=运算符或通过-=运算符来实现添加或删除方法。匿名委托是指在使用匿名方法注册在委托上,通过定义代码块来实现委托的作用。以上是关于C#委托的定义、应用及示例全部内容,委托内容还有很多,敬请关注后续内容。委托的使用需遵循三步走原则,分别是定义委托、实例化委托,调用委托。定义声明委托后就可以实例化委托,其语法形式为。

dotNet开发技术分享 1180

从零开始,手把手教你用RTL代码设计一个简单的8位CPU(附状态图与ALU设计)

本文详细介绍了如何从零开始设计一个简单的8位CPU,包括状态机设计、ALU实现与RTL编码实战。通过具体的指令集分析、状态图设计和Verilog代码示例,帮助读者深入理解CPU工作原理,并掌握RTL代码编写技巧。特别适合计算机系统学习者和硬件设计爱好者。

weixin_30847063的博客 320

委托的使用与原理简析

委托的使用与原理简析:委托为什么本质上是数据类型?委托变量直接执行了方法背后原理是什么?多播委托是怎么实现的?

敦格 6155

OpenAI,从推出更强大的Sora 2模型展开探索与未来发展前景+部署方法大全+文末邀请码*12

摘要 OpenAI推出的Sora 2是第二代AI视频生成模型,在多模态内容生成领域实现重大突破。文末足足有12个邀请码,速来速享!!!

aqfcca的博客 2248

Python遥感图像处理应用篇(二十三):Python+GDAL 批量拼接图像

遥感影像拼接分多种不同的情况,比如比较常用的是两幅影像拼接或者多个图像合并为一个图像。GDAL中实现影像拼接的方式也有多种,比如常用可以通过numpy读取影像数组,并计算各个图像的numpy数组范围,合并多个numpy数组为一个最终的结果,并将其重新输出为一幅新的图像,即可实现图像的拼接。另外比较方便的一种方法便是使用GDAL.warp()函数方法。这个函数的功能很多,可以实现多种不同的目的,比如用于坐标系转换、投影变换、图像合并与镶嵌、地理范围裁剪、更改分辨率、矢量裁剪等多种功能。这些功能可以通过设置Op

soderayer的博客 4643

UE4之多播委托

参考: https://docs.unrealengine.com/zh-CN/Programming/UnrealArchitecture/Delegates/Multicast/index.html 概念: 可以绑定到多个函数并一次性同时执行它们的委托。 这里我计划使用多播委托开两个灯 多播委托的定义: DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam 定义的委托的类型必须是F开头 所以我定义的函数如下 DECLAR...

1921

【MATLAB】STM32电机调速闭环控制工程

本文提出了一种基于MATLAB仿真与STM32实现的直流电机闭环PID调速控制方案。通过MATLAB建立电机数学模型并进行参数整定,仿真验证了增量式PID算法在启停、稳态和抗扰动方面的优越性能。基于STM32F103搭建了硬件系统,实现了编码器测速、定时中断控制、PWM输出等功能。实测表明,该系统转速超调<2%、稳态误差±2r/min,具备快速响应和强抗扰能力。相比开环控制,闭环调速显著提升了动态性能和稳态精度。方案提供了完整的仿真代码和嵌入式工程源码,可直接应用于智能小车、工业传动等场景,具有较高的

unber的博客 50

UE4 C++ 多播委托(代理)

2021-2-15 官方文档 多播委托 多播委托拥有大部分与单播委托相同的功能。它们只拥有对对象的弱引用,可以与结构体一起使用,可以四处轻松复制等等。 就像常规委托一样,多播委托可以远程加载/保存和触发;但多播委托函数不能使用返回值。它们最适合用来 四处轻松传递一组委托。 事件 是一种特殊类型的多播委托,它在访问"Broadcast()"、"IsBound()"和"Clear()"函数时会受到限制。 声明多播委托 多播委托在声明方式上与声明标准委托 相同,只是前者使用特定于多播委托的宏变体。 ...

walsyker的博客 4514

多算法数据预测——BP、ELM、LSTM、BiLSTM和SAELSTM,附Matlab源码

本文将为大家介绍基于BP、ELM、LSTM、BiLSTM和SAELSTM多种算法的数据预测,并提供相应的Matlab源码。SAELSTM算法是一种结合自动编码器和LSTM神经网络的深度学习方法,用于时间序列数据预测。ELM算法是一种单层前向神经网络,在单次训练过程中直接产生输出权重,从而具有快速学习和良好推广性能。多算法数据预测——BP、ELM、LSTM、BiLSTM和SAELSTM,附Matlab源码。总体来看,采用多种算法进行数据预测可以提高预测准确率,并可根据不同场景选择适合的算法。

qq_39605374的博客 862

YOLOv11改进策略【注意力机制篇】| SE、CBAM、ECA、CA、Swin Transformer等注意力机制全面解析与应用

本文详细介绍了五种主流的注意力机制及其在YOLOv11中的应用。通过合理的模块选择和位置部署,注意力机制能够显著提升目标检测性能。

QQ_778132974的博客 876

委托

一.委托的概念 委托是一种在对象里保存方法的引用,也是一种类型安全的函指针。 继承是System.MulicastDelegate,任何委托都是多播委托。在IL层中,委托就是一个类。IL(中间语言,高级语言(如C#等)-----中间语言(IL)---计算机识别语言) 二委托语法 声明委托 public delegate v...

dianchanchan1786的博客 112

使用Python的OpenCV库进行三维重建点云

通过这些步骤,我们可以使用Python的OpenCV库进行三维重建,并生成对应的点云。当然,这只是一个简单的示例,实际的三维重建可能涉及更多的图像处理和计算步骤。在计算机视觉领域,三维重建是一项重要的任务,它可以将多个二维图像或视频序列转换为三维场景模型。在本文中,我们将介绍如何使用Python的OpenCV库进行三维重建,并生成相应的点云。以上是使用Python的OpenCV库进行三维重建点云的简要介绍和示例代码。最后,我们可以将计算得到的三维点云可视化。安装完成后,我们可以开始编写代码。

AuSwift的博客 1646

【UE5 C++课程系列笔记】09——多播委托的基本使用

目录: 多播委托——申明委托 一、DECLARE_MULTICAST_DELEGATE 二、DECLARE_DYNAMIC_MULTICAST_DELEGATE 多播委托——绑定委托 一、Add 二、AddStatic 三、AddRaw 四、AddSP 五、AddUObject 六、Remove 七、RemoveAll 多播委托——执行 载荷数据

ChaoChao66666的博客 2126

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

c#委托总结

委托一、什么是委托二、委托的定义和使用三、委托的应用,小例子:12306卖票四、多播委托 一、什么是委托 顾名思义,委托就是让别人做事。委托是实现回调函数的一种机制。可能有人会问了,回调函数是个啥??? 举个例子:我现在是一家公司的老板,公司现在在招聘.NET工程师,我们有一个小姐姐专门负责接受求职者投递的简历,我就告诉这个小姐姐,一旦收到新的简历就转发给我一份。 这个例子里小姐姐要做的工作:给我转发一份简历(回调函数里的操作),就是一个回调函数的作用。一旦有了满足条件(收到了新的简历),小姐姐就会转发给我

zwl995的博客 396

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C#委托

委托和类一样,是数据类型,等同于c++的函数指针。可以看做是个特殊的类。 格式:delegate 返回值 委托名<泛型>(参数) 返回值 方法名(参数) 委托包含并可执行具有相同签名和返回值类型的有序方法列表。 当委托被调用时,它调用列表中的每一个方法。 1、委托加载你指定的n个同样签名的方法,不一定是所有; 2、委托本身是没有委托体“{}”, 所以他没有类似类的自定义数据成员(字段、...

weixin_42530700的博客 128

zy74_C#多播委托、匿名函数、Lambda表达式

zy74_C#多播委托、匿名函数、Lambda表达式

weixin_47149785的博客 467

C# 委托(什么是委托)

如果你有C++背景,理解委托最快的方法是把它看成一个类型安全的、面向对象的C++可以认为委托是持有一个或多个方法的对象。本章将揭示创建和使用委托的语法和语义。在本章后面,你将看到如何使用委托将可执行的。我们将从下面的示例代码开始。如果此时你有些东西弄不明白,不必担心,本章后面会介绍。由于我们使用了随机数生成器,程序在不同的运行过程中会产生不同的值。象,但委托与典型的对象不同。可以执行委托,这时委托会执行它所“持有"的方法。代码从一个方法传递到另一个方法,以及为什么这样做是非常有用的。

钢铁男儿 472

在C++中使用委托实现多播

在C++中使用委托实现多播

qq_33945243的博客 422

C#委托&多播委托

在 C# 中,是一种类型安全的函数指针,用于封装方法的引用。它允许将方法作为参数传递、存储或异步调用。输出结果:执行加法:结果为:15执行减法:结果为:5执行乘法:结果为:50。

m0_68647295的博客 239

C#之委托

C#之委托

m0_37546766的博客 114

第十七章 委托

1.委托理解为函数指针就可以了,指向需要执行的函数。 2.派生关系:继承自MulticastDelegate内部信息不多讲了,把握住几个点就行了,有个函数指针_methodPtr指向了需要执行的函数地址。按照绑定顺序执行,多个委托方法存贮在 _invocationList中。 3.泛型委托:很多 泛型委托是为了解决相似的委托过多的问题,NET提供的泛型委托17个参数不同的Action委托和...

weixin_34099526的博客 132

unity事件委托简介

写成事件之后就变成了:public delegate void XXX()、public event xxx delegate_1()区别于Action,在Action后面的括号中写返回值,那么注册在其中的函数都会返回值,那么这个返回值就会不停更新。delegate(容器).Invoke()执行的时候,所有在注册在这个容器delegate内的函数都会被执行。例如:public delegate void XXX()、public xxx delegate_1();

LAIbad的博客 284
上一篇: Git提交权限不足
下一篇: 分享WPF的UI开源库
Aflashstar
博客等级 码龄12年 205粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值