通过委托执行多个函数

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

相关推荐

服务器AutoDL自己部署QWen3

说明:核心参数:30B 模型原精度权重文件约 60GB,单张 PRO 6000 拥有 48GB 显存,单卡塞不下原精度模型,2张 PRO 6000 = 96GB 总显存,这不仅能装下模型,还能留出约 30GB 显存给 KV Cache(上下文长度) 以及 Omni 多模态组件 处理图片/视频输入时的额外开销。1. 前提准备模型选择:直接下载到 AutoDL 服务器上=》原精度模型(BF16/FP16) 的 Qwen3-Omni-30B,选择的示例和环境如下。# 3. 正式执行模型下载。

xiaoxiao_00001的博客 415

C#中委托的应用与示例

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

dotNet开发技术分享 1180

ESP-Mesh-Lite vs ESP-Mesh:如何选择适合你的物联网组网方案?

本文深入对比了乐鑫ESP-Mesh-Lite与ESP-Mesh两种物联网组网方案的核心差异。重点解析了ESP-Mesh-Lite分布式协议栈架构的优势,即每个节点拥有独立IP,可直接访问外部网络,极大简化了应用层开发。文章从网络架构、性能、开发体验及适用场景等多维度进行分析,为开发者根据项目需求(如分布式数据采集、智能家居或集中控制网络)选择最合适的方案提供了清晰的决策框架。

pluto的博客 817

委托的使用与原理简析

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

敦格 6155

COLMAP性能优化实战:如何用GPU加速和并行计算让重建速度提升300%

本文详细介绍了如何通过GPU加速、并行计算和参数调优显著提升COLMAP的三维重建效率。从硬件资源分配到计算流程优化,再到大型数据集的分块处理策略,全面解析了将重建速度提升300%以上的实用技巧,特别适合处理无人机航拍和室内扫描等大规模三维重建项目。

weixin_29098391的博客 202

Unity游戏开发实战:用柏林噪声打造3D随机地形(附完整C#代码)

本文详细介绍了如何在Unity游戏开发中使用柏林噪声算法生成3D随机地形,包含完整的C#代码实现。从基础柏林噪声原理到高级参数控制,再到性能优化和常见问题解决,帮助开发者掌握程序化地形生成技术,打造丰富多变的游戏世界。

weixin_29281941的博客 101

UE4之多播委托

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

1921

freertos移植心得

1.freertos移植msp430 今天终于移植成功了freertos。现在写下这篇博文来整理这一路移植过程中遇到的问题和心得。 由于使用的是IAR FOR MSP430的IDE,博文只讨论在IAR下的移植。本文针对的是官方支持的平台架构下的移植,不使用官方提供的demo,得到的是一个纯洁版的系统。 1.下载源代码 在freertos的官网下载一份最新的源代码点击打开链接。 2.选择平

一条狗的博客 4173

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

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

walsyker的博客 4514

深入解析时钟同步技术:相位同步、频率同步与同源时钟的实战应用

本文深入解析时钟同步技术的三种核心方式:相位同步、频率同步与同源时钟,详细阐述其技术原理、实现方案及实战应用。通过对比分析不同同步方式的特点与适用场景,为电子系统设计提供选型指南,帮助工程师优化时钟网络设计,提升系统稳定性和性能。

weixin_29240711的博客 449

告别信号干扰!用Altium Designer 19搞定4层/6层PCB叠层设计的保姆级流程

本文详细介绍了如何使用Altium Designer 19进行4层/6层PCB叠层设计,解决信号干扰问题。通过实际案例和系统方法论,涵盖高速数字电路、混合信号系统等典型场景的设计优化,帮助硬件工程师和学生掌握电磁兼容(EMC)与信号完整性(SI)的核心技术。

weixin_27076351的博客 206

委托

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

dianchanchan1786的博客 112

飞牛fnNAS搭建私有云音乐库

本文介绍了在飞牛NAS上部署Navidrome音乐服务器的完整流程。首先创建音乐存储目录并安装Navidrome应用,然后配置管理员账号、语言设置和音乐路径。接着详细说明使用"音乐标签"软件刮削音乐元数据的方法,包括获取软件、导入音乐文件和自动匹配标签。针对远程访问需求,推荐使用ZeroTier实现内网穿透,并给出注册、创建网络及设备加入的具体步骤。最后介绍移动端使用"音流"APP连接Navidrome服务器的配置方法,实现手机端音乐播放。通过这套方案,用户可以搭建专

dgnankai的专栏 1823

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

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

ChaoChao66666的博客 2126

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

c#委托总结

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

zwl995的博客 396

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

余额充值