用回调函数显示控制器程序执行进度

Action<double, double> OnFeedbackProgramLine { get; set; } 是C#中的委托属性,用于实现回调机制。下面从理解和使用两方面详细说明:


1. 核心理解

1.1 类型解析
  • Action<double, double>
    表示一个接受两个double类型参数且无返回值的方法的委托。等价于:

public delegate void MyDelegate(double arg1, double arg2);
  • 属性作用
    提供外部订阅程序执行进度反馈的能力,典型场景:

    • 当前执行的行号

    • 总行数百分比

1.2 设计意图
  • 解耦:控制器内部不直接依赖UI,通过委托通知进度。

  • 灵活性:外部可动态注入回调逻辑(如更新进度条、日志输出)。


2. 使用方式

2.1 订阅回调

外部代码(如ViewModel)订阅反馈事件:

var controller = new A3200Controller();
controller.OnFeedbackProgramLine = (currentLine, totalLines) => 
{
    // 更新UI进度条
    ProgressBar.Value = (currentLine / totalLines) * 100;
    Console.WriteLine($"进度: {currentLine}/{totalLines}");
};
2.2 内部触发

在控制器内部(如DiagnosticPacketReceived事件中),当检测到程序行号变化时调用:

private void DiagnosticPacketReceived(object sender, NewDiagPacketArrivedEventArgs e)
{
    if (taskInfo.State == TaskState.ProgramRunning)
    {
        int currentLine = e.Data.Tasks[TaskId.T01].ProgramLine.LineNumber;
        double totalLines = cmdStrLists.Sum(lst => lst.Count);
        OnFeedbackProgramLine?.Invoke(currentLine, totalLines); // 触发回调
    }
}
2.3 安全调用
  • 空值检查:使用?.操作符避免未订阅时抛异常。

  • 线程切换:若需更新UI,应在回调内调度到UI线程(如WPF中的Dispatcher):

controller.OnFeedbackProgramLine = (current, total) => 
{
    Application.Current.Dispatcher.Invoke(() => 
    {
        ProgressText.Text = $"{current}/{total}";
    });
};

3. 实际应用场景

场景1:实时进度显示
// 在View模型中订阅
controller.OnFeedbackProgramLine += (line, total) => 
{
    Progress = line / total * 100;
    Status = $"执行中: {line}行/共{total}行";
};

// 绑定到UI(以WPF为例)
<ProgressBar Value="{Binding Progress}" />
<TextBlock Text="{Binding Status}" />
场景2:执行日志记录
controller.OnFeedbackProgramLine += (line, _) => 
{
    Logger.Info($"正在执行第{line}行...");
};

4. 注意事项

  1. 生命周期管理

    • 若控制器为长生命周期对象,需在不再需要时取消订阅:

// 取消单个回调
controller.OnFeedbackProgramLine -= YourCallbackMethod;

// 清空所有回调
controller.OnFeedbackProgramLine = null;
  1. 性能考量

    • 避免在回调中执行耗时操作(如数据库访问),否则会阻塞运动控制线程。

  2. 多线程安全

    • 回调可能在非UI线程触发,操作UI时必须切换线程(如WPF的Dispatcher.Invoke)。


5. 扩展对比

  • 与事件(Event)的区别

    • Action属性更轻量,适合单播(单个订阅者)。

    • 事件(event)支持多播(多个订阅者),但需要显式定义委托类型。

  • 替代方案
    若需更复杂的交互,可改用IObservable(响应式编程)或IProgress<T>接口。

通过这种设计,运动控制器能够将内部执行状态安全、高效地通知到外部模块,典型应用于工业控制软件的实时监控界面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值