通过委托执行多个函数

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#的大多数人都没有用过这两门语言,因此对委托的理解不是很深,对于委托可以简单的从字面去理解,即“委托别人去执行某些操作”,也就是说执行一个操作,而这个操作过程自身并不知道,只是委托过来让你去执行而已。参看如下这个例子。 阅读详情

相关推荐

Windows Server 2019整机备份与异机还原实战:从虚拟机到物理机的完整迁移指南

本文详细介绍了Windows Server 2019整机备份与异机还原的实战操作,涵盖从虚拟机到物理机的完整迁移流程。通过环境准备、备份策略设计、具体操作步骤及迁移后优化等内容,帮助用户实现系统环境的无缝迁移,特别适用于服务器硬件升级、数据中心迁移等场景。

weixin_30555125的博客 133

C#中委托的应用与示例

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

dotNet开发技术分享 1180

【论文导读】ICDM2018|SASRec---基于自注意力机制的序列推荐(召回)

前言本次分享2018年发表在ICDM上的论文----「Self-Attentive Sequential Recommendation」。主要是应用self-attention机制来做一...

Blank_Space 8033

委托的使用与原理简析

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

敦格 6155

afe模拟前端的重要性_高性能模拟前端信号链解决方案如何助力医疗超声系统发展...

1942年,奥地利TDussik使用A型超声成像系统穿透性探测颅脑,并于1949年获得头部的超声图像,此举昭示超声系统进入到医疗领域。直到如今,超声系统作为用于人体内部的无创可视化技术,被广泛用于医疗领域。最近一份报告称到2022年,中国医疗超声诊断仪器行业的市场规模预计将达到15.8亿美元,保持6%左右的年均增长率。高性能模拟信号链前端是超声设备的关键组成部分,作为高性能模拟技术主要的提供商AD...

weixin_28799111的博客 1088

单细胞拟时序分析实战:用monocle2从Seurat对象构建细胞轨迹(附完整代码)

本文提供了一套完整的单细胞拟时序分析实战教程,详细讲解了如何将Seurat对象转换为Monocle2的CellDataSet,并构建细胞命运轨迹。内容涵盖数据转换、轨迹定义基因选择、降维参数调优、可视化技巧及结果生物学验证,旨在帮助研究者解决实际分析中的常见问题,从静态细胞图谱中挖掘动态发育过程。

weixin_29251337的博客 342

UE4之多播委托

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

1921

kettle多表数据迁移

点击 文件——新建——作业,在左侧的 核心对象 标签下选择 通用,双击添加一个 start ,一个 转换 ,一个 作业 和一个 成功 到右侧的作业面板,这些作业项都可以改名字。点击文件—新建—转换,在左侧的 核心对象 标签下选择 输入 下的 表输入,双击添加到右侧的转换面板,再选择 作业 下的 复制记录到结果 ,双击添加到右侧的转换面板。新建转换,在左侧的 核心对象 标签下选择 作业 下的 从结果获取记录,双击添加到右侧的转换面板,再选择 作业 下的 设置变量 ,双击添加到右侧的转换面板。

u014061745的博客 1342

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

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

walsyker的博客 4514

LangGraph实战:用Plan-and-Execute模式5步搭建智能问答机器人(附Tavily搜索集成)

本文详细介绍了如何利用LangGraph的Plan-and-Execute模式,通过规划、执行、动态调整三个核心阶段,构建一个能够处理复杂多步骤问题的智能问答机器人。文章提供了从环境配置、状态管理到核心节点(规划、执行、重新规划)实现的完整实战指南,并集成了Tavily搜索工具,展示了如何将智能任务规划应用于实际信息查询场景。

weixin_29258297的博客 341

【Matlab】多旋翼无人机视觉伺服跟踪控制程序

本文介绍了基于Matlab的多旋翼无人机视觉伺服跟踪控制程序开发方法。该系统采用视觉感知、坐标转换、伺服控制和仿真验证四个核心模块,通过HOG+SVM目标检测、Shi-Tomasi特征提取和PID双闭环控制算法实现动态目标跟踪。详细阐述了相机标定、目标检测、坐标转换及伺服控制等关键环节的Matlab实现代码,并进行了仿真验证。结果表明该系统在±0.1m的跟踪精度下可实现100Hz的实时处理,适用于室内外复杂场景。文章还提出了工程应用中的优化建议,为无人机视觉伺服系统的开发提供了完整的技术方案。

unber的博客 507

委托

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

dianchanchan1786的博客 112

Android 9.0 SystemUI禁用长按recent键的分屏功能

​ 在9.0的系统产品开发中,系统对于多窗口模式默认会有分屏功能的,但是在某些产品中,需要禁用分屏模式,所以需要在导航栏中 禁用长按recent的分屏模式功能,接下来分析下相关分屏模式的实现 ​

安卓兼职framework和app工程师的博客 448

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

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

ChaoChao66666的博客 2126

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

c#委托总结

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

zwl995的博客 396

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

C#委托

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

weixin_42530700的博客 128

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

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、付费专栏及课程。

余额充值