大山的LabVIEW/TestStand分享大山的LabVIEW/TestStand分享

面向 LabVIEW 与 TestStand 的个人知识分享站

LabVIEW vs C#:用户事件机制深入对比

LabVIEW vs C#:用户事件机制深入对比

从 LabVIEW 的 User Event 到 C# 的 Event,一路贯通两种事件模型的设计哲学与实现细节

语法User Event
发布时间:2026-07-17阅读时长:30 分钟浏览 70访客仅可浏览正文内容
概念LabVIEW User EventC# Event
事件的定义Create User Event VI(创建事件引用)event EventHandler<T> 关键字声明
事件引用 / 类型Event Refnumevent 字段本身(强类型)
订阅者注册Register For Events 节点+= 运算符
订阅者注销Unregister For Events 节点-= 运算符
事件的触发Generate User Event VI?.Invoke(this, args)
事件数据的载体Event Data 端子(可以是任意类型组成的 Cluster)EventArgs 子类或泛型参数
处理事件的代码Event Structure 中的事件分支Lambda 表达式 / 命名方法
多播能力多个 Event Structure 可注册同一事件多个方法可 += 到同一事件
LabVIEW — Create User Event
C# — event 关键字
public event EventHandler<string>? Clicked;
LabVIEW — Register For Events
C# — += 订阅
btn.Clicked += (sender, name) =>
{
    Console.WriteLine($"收到: {name}");
};
LabVIEW — Generate User Event
C# — ?.Invoke()
Clicked?.Invoke(this, buttonName);
LabVIEW — Event Structure
C# — Lambda / 方法
// sender = 触发事件的对象
// args   = 事件携带的数据
(sender, args) =>
{
    string name = args;    // 获取数据
    // ... 处理逻辑
};
LabVIEW — Unregister For Events
C# — -= 取消订阅
btn.Clicked -= handler;
对比.jpeg
两种语言的对比
C#代码
/* ═══════════════════════════════════════════════
 *  事件(Event)最简演示
 *  一句话理解:事件 = 发生某件事时,自动通知所有订阅者
 *
 *  LabVIEW 对照:User Event
 *    Create User Event  →  event 关键字声明
 *    Register For Events →  += 订阅
 *    Generate User Event →  ?.Invoke() 触发
 *    Event Structure     →  lambda 或命名方法
 *  ═══════════════════════════════════════════════ */

using System;

class Button
{
    // 步骤1:声明事件
    // event 关键字 + EventHandler 是 .NET 标准写法,内置委托
    public event EventHandler<string>? Clicked;

    // 步骤2:触发事件的方法
    // ?.Invoke 的作用:如果没人订阅(null),就跳过,不报错
    public void Click(string buttonName)
    {
        Console.WriteLine($"[按钮] \"{buttonName}\" 被按下");
        Clicked?.Invoke(this, buttonName);  // 通知所有订阅者,调用委托
    }
}

class Program
{
    static void Main()
    {
        var btn = new Button();

        // 步骤3:订阅事件(+=),委托的多播订阅
        btn.Clicked += (sender, name) =>
        {
            Console.WriteLine($"  → 订阅者1: 收到! 按钮是 \"{name}\"");
        };
        //Lambda 表达式(被编译器转为委托的实例)

        // 把 lambda 存成变量,后面才能取消订阅,指向一个委托实例的变量
        EventHandler<string> sub2 = (sender, name) =>
        {
            Console.WriteLine($"  → 订阅者2: 我也收到了 \"{name}\"");
        };
        btn.Clicked += sub2;  //委托的多播订阅 

        Console.WriteLine("(当前有 2 个订阅者)");
        Console.WriteLine();

        // 步骤4:触发(两个订阅者都会收到)
        btn.Click("开始采集");

        // 步骤5:取消订阅(-=),然后再次触发
        btn.Clicked -= sub2;  // 订阅者2 不再接收通知

        Console.WriteLine();
        Console.WriteLine("(订阅者2 已取消,只剩 1 个订阅者)");
        Console.WriteLine();
        btn.Click("停止采集"); // 只有订阅者1 会收到
    }
}

/* ═══════════════════════════════════════════════
 *  运行输出:
 *
 *  (当前有 2 个订阅者)
 *
 *  [按钮] "开始采集" 被按下
 *    → 订阅者1: 收到! 按钮是 "开始采集"
 *    → 订阅者2: 我也收到了 "开始采集"
 *
 *  (订阅者2 已取消,只剩 1 个订阅者)
 *
 *  [按钮] "停止采集" 被按下
 *    → 订阅者1: 收到! 按钮是 "停止采集"
 *                           ↑ 订阅者2 不再出现
 *
 *  ──────────── 三步速记 ────────────
 *  1. 声明:public event EventHandler<T> xxx;
 *  2. 订阅:xxx += (sender, args) => { ... };
 *  3. 触发:xxx?.Invoke(this, data);
 *  4. 取消:xxx -= handler;  // ← 别忘了!
 *  ═══════════════════════════════════════════════ */

附件下载

留言区

只有注册用户可以留言和下载附件。立即注册已有账号,去登录
正在加载留言...