逻辑规则和CAN结合的更改
This commit is contained in:
@@ -42,7 +42,7 @@ namespace CapMachine.Wpf.Services
|
||||
/// Key: 规则名称, Value: 已编译的Lambda表达式
|
||||
///private readonly ConcurrentDictionary<string, Func<double, double>> _expressionCache;
|
||||
/// </summary>
|
||||
private readonly ConcurrentDictionary<string, Lambda> _expressionCache;
|
||||
private readonly ConcurrentDictionary<string, Func<double, double>> _expressionCache;
|
||||
|
||||
///// <summary>
|
||||
///// 创建包含指定值的参数数组
|
||||
@@ -60,7 +60,7 @@ namespace CapMachine.Wpf.Services
|
||||
/// </summary>
|
||||
private Parameter CreateParameters(double value)
|
||||
{
|
||||
return new Parameter("value", typeof(double),value);
|
||||
return new Parameter("value", typeof(double), value);
|
||||
|
||||
}
|
||||
|
||||
@@ -76,13 +76,10 @@ namespace CapMachine.Wpf.Services
|
||||
// 初始化集合
|
||||
LogicRuleDtos = new ObservableCollection<LogicRuleDto>();
|
||||
|
||||
_expressionCache = new ConcurrentDictionary<string, Lambda>();
|
||||
_expressionCache = new ConcurrentDictionary<string, Func<double, double>>();
|
||||
|
||||
// 初始化DynamicExpresso解释器
|
||||
CurInterpreter = new Interpreter();
|
||||
//.Reference(typeof(Math)) // 引用Math类
|
||||
// //.SetVariable("Math", typeof(Math))
|
||||
//.SetVariable("value", 0.2);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -228,7 +225,7 @@ namespace CapMachine.Wpf.Services
|
||||
/// 更新规则
|
||||
/// </summary>
|
||||
/// <param name="rule">规则对象</param>
|
||||
public void UpdateRule(LogicRule rule)
|
||||
public void UpdateRule(LogicRule ruleOld,LogicRule rule)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(rule.Name))
|
||||
{
|
||||
@@ -269,8 +266,8 @@ namespace CapMachine.Wpf.Services
|
||||
LogicRuleDtos.Insert(insertIndex - 1, Mapper.Map<LogicRuleDto>(rule));
|
||||
}
|
||||
|
||||
|
||||
_expressionCache.TryRemove(updatedDto.Name, out _);
|
||||
//有可能更改的是名称,那么新名称的话在_expressionCache中肯定是找不到的,可以用之前的ruleOld
|
||||
_expressionCache.TryRemove(ruleOld.Name!, out _);
|
||||
CacheExpression(updatedDto);
|
||||
}
|
||||
}
|
||||
@@ -412,39 +409,6 @@ namespace CapMachine.Wpf.Services
|
||||
return rule;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 应用逻辑转换 - 主要使用方法
|
||||
/// </summary>
|
||||
/// <param name="value">输入值</param>
|
||||
/// <param name="ruleName">规则名称</param>
|
||||
/// <returns>转换后的输出值</returns>
|
||||
public double ApplyLogic(double value, string ruleName)
|
||||
{
|
||||
var rule = GetRuleByName(ruleName);
|
||||
|
||||
return ApplyExpression(value, rule);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 应用逻辑转换(基于参数类型自动选择规则)
|
||||
/// </summary>
|
||||
/// <param name="value">输入值</param>
|
||||
/// <param name="parameterType">参数类型</param>
|
||||
/// <returns>转换后的输出值</returns>
|
||||
public double ApplyLogicByType(double value, string parameterType)
|
||||
{
|
||||
var rules = GetRulesByParameterType(parameterType).ToList();
|
||||
if (rules.Count == 0)
|
||||
{
|
||||
LogService.Warn($"未找到适用于 {parameterType} 的转换规则,将返回原始值");
|
||||
return value;
|
||||
}
|
||||
|
||||
// 如果存在多个规则,取第一个
|
||||
var rule = rules.First();
|
||||
|
||||
return ApplyExpression(value, rule);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将规则表达式预编译并缓存到字典中
|
||||
@@ -459,13 +423,17 @@ namespace CapMachine.Wpf.Services
|
||||
|
||||
try
|
||||
{
|
||||
// ****如下步骤很重要,尝试了很多次才正常运行****
|
||||
|
||||
// 使用已有的CreateParameters方法创建参数声明
|
||||
var parameter = CreateParameters(0); // 值不重要,只是为了获取参数声明
|
||||
// 只解析一次,得到 Lambda 对象
|
||||
var lambda = CurInterpreter.Parse(rule.Expression, parameter); // 只定义参数类型,不传值
|
||||
// 编译为强类型委托
|
||||
var compiledFunc = lambda.Compile<Func<double, double>>();
|
||||
|
||||
// 存入缓存
|
||||
_expressionCache[rule.Name] = lambda;
|
||||
_expressionCache[rule.Name] = compiledFunc;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -557,114 +525,54 @@ namespace CapMachine.Wpf.Services
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 临时测试用
|
||||
/// 快速的执行数据
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="rule"></param>
|
||||
/// <returns></returns>
|
||||
public double ApplyExpressionNoCache(double value, LogicRuleDto rule)
|
||||
public double ApplyExpressionFast(double value, LogicRuleDto rule)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!_expressionCache.TryGetValue(rule.Name, out var CurActiveFunc))
|
||||
{
|
||||
CacheExpression(rule);
|
||||
if (!_expressionCache.TryGetValue(rule.Name, out CurActiveFunc))
|
||||
return value;
|
||||
}
|
||||
|
||||
CurInterpreter.SetVariable("value", value);
|
||||
var lambda = CurInterpreter.Parse(rule.Expression);
|
||||
return (double)lambda.Invoke();
|
||||
|
||||
//// 创建全新的解释器实例
|
||||
//var localInterpreter = new Interpreter()
|
||||
// .Reference(typeof(Math))
|
||||
// .SetVariable("Math", typeof(Math));
|
||||
|
||||
//// 直接设置变量值而不是使用参数
|
||||
//localInterpreter.SetVariable("value", value);
|
||||
//// 解析并执行
|
||||
//var result = localInterpreter.Eval<double>(rule.Expression);
|
||||
//Console.WriteLine($"直接执行: 输入={value}, 表达式={rule.Expression}, 结果={result}");
|
||||
//return result;
|
||||
// 直接调用委托,无反射开销
|
||||
return CurActiveFunc(value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch
|
||||
{
|
||||
LogService.Error($"直接执行表达式失败: {ex.Message}");
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 批量应用逻辑转换 (高性能版本)
|
||||
/// 如果需要对多个数据应用相同规则,考虑实现批处理版本:
|
||||
/// </summary>
|
||||
/// <param name="values">原始值字典(键为参数名称,值为原始值)</param>
|
||||
/// <returns>转换后的值字典</returns>
|
||||
public Dictionary<string, double> ApplyBatchLogic(Dictionary<string, double> values)
|
||||
/// <param name="values"></param>
|
||||
/// <param name="rule"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<double> ApplyExpressionBatch(IEnumerable<double> values, LogicRuleDto rule)
|
||||
{
|
||||
// 为了性能,预分配容量
|
||||
var result = new Dictionary<string, double>(values.Count);
|
||||
|
||||
// 缓存参数类型到规则的映射,避免重复查询
|
||||
var cachedRulesByType = new Dictionary<string, LogicRuleDto>();
|
||||
|
||||
foreach (var entry in values)
|
||||
if (!_expressionCache.TryGetValue(rule.Name, out var func))
|
||||
{
|
||||
var paramName = entry.Key;
|
||||
var origValue = entry.Value;
|
||||
|
||||
try
|
||||
{
|
||||
// 获取参数类型
|
||||
var paramType = DetermineParameterType(paramName);
|
||||
|
||||
// 尝试从缓存获取规则
|
||||
if (!cachedRulesByType.TryGetValue(paramType, out var rule))
|
||||
{
|
||||
var rules = GetRulesByParameterType(paramType).ToList();
|
||||
if (rules.Count > 0)
|
||||
{
|
||||
rule = rules.First();
|
||||
cachedRulesByType[paramType] = rule; // 添加到缓存
|
||||
}
|
||||
}
|
||||
|
||||
// 如果找到规则,应用转换
|
||||
if (rule != null)
|
||||
{
|
||||
var convertedValue = ApplyExpression(origValue, rule);
|
||||
result.Add(paramName, convertedValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Add(paramName, origValue); // 没有规则时使用原始值
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogService.Error($"处理参数 {paramName} 失败: {ex.Message}");
|
||||
result.Add(paramName, origValue); // 出错时使用原始值
|
||||
}
|
||||
CacheExpression(rule);
|
||||
if (!_expressionCache.TryGetValue(rule.Name, out func))
|
||||
return values;
|
||||
}
|
||||
|
||||
return result;
|
||||
// 使用并行处理大量数据
|
||||
return values.AsParallel().Select(v =>
|
||||
{
|
||||
try { return func(v); }
|
||||
catch { return v; }
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从参数名称确定参数类型
|
||||
/// </summary>
|
||||
/// <param name="paramName">参数名称</param>
|
||||
/// <returns>参数类型</returns>
|
||||
private string DetermineParameterType(string paramName)
|
||||
{
|
||||
// 根据参数名称确定类型的逻辑
|
||||
// 这里使用简单的名称匹配,实际项目中可能需要更复杂的映射
|
||||
if (paramName.Contains("速度") || paramName.Contains("转速"))
|
||||
return "转速";
|
||||
else if (paramName.Contains("功率") || paramName.Contains("pw") || paramName.Contains("power"))
|
||||
return "功率";
|
||||
else if (paramName.Contains("温度") || paramName.Contains("temp"))
|
||||
return "温度";
|
||||
else if (paramName.Contains("压力") || paramName.Contains("press"))
|
||||
return "压力";
|
||||
|
||||
// 默认类型
|
||||
return "通用";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user