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. 注意事项
-
生命周期管理
-
若控制器为长生命周期对象,需在不再需要时取消订阅:
-
// 取消单个回调
controller.OnFeedbackProgramLine -= YourCallbackMethod;
// 清空所有回调
controller.OnFeedbackProgramLine = null;
-
性能考量
-
避免在回调中执行耗时操作(如数据库访问),否则会阻塞运动控制线程。
-
-
多线程安全
-
回调可能在非UI线程触发,操作UI时必须切换线程(如WPF的
Dispatcher.Invoke
)。
-
5. 扩展对比
-
与事件(Event)的区别
-
Action
属性更轻量,适合单播(单个订阅者)。 -
事件(
event
)支持多播(多个订阅者),但需要显式定义委托类型。
-
-
替代方案
若需更复杂的交互,可改用IObservable
(响应式编程)或IProgress<T>
接口。
通过这种设计,运动控制器能够将内部执行状态安全、高效地通知到外部模块,典型应用于工业控制软件的实时监控界面。