diff --git a/CapMachine.Wpf/Services/PPCService.cs b/CapMachine.Wpf/Services/PPCService.cs
index b980917..3b6497c 100644
--- a/CapMachine.Wpf/Services/PPCService.cs
+++ b/CapMachine.Wpf/Services/PPCService.cs
@@ -256,67 +256,43 @@ namespace CapMachine.Wpf.Services
//textBox5.Text = "";
- string hpath = SuperHeatCoolConfig.FluidsPath;
- long size = hpath.Length;
-
- hpath += new String(' ', 255 - (int)size);
- IRefProp64.SETPATHdll(hpath, ref size);
-
- long numComps = 1;//冷媒个数
- //string hfld = "R1234YF.FLD"; R1234YF
- string hfld = "";
- if (SuperHeatCoolConfig.Cryogen == "R134a")
+ // 幂等初始化:仅首次或工质/路径变化时执行 SETPATH/SETUP,提高每秒循环效率
+ if (!EnsureRefpropInitialized(out var initErr))
{
- hfld = "R134A.FLD";
- }
- else
- {
- hfld = "R134A.FLD";
- }
- //string hfld = "R134A.FLD";
- //string hfld = Convert.ToString(comboBox1.Text);//从控件获取数据
- size = hfld.Length;
-
- hfld += new String(' ', 10000 - (int)size);
-
- //string hfmix = "hmx.bnc" + new String(' ', 255);//原来的
- string hfmix = "hmx.bnc" + new String(' ', 255);//248
- string hrf = "DEF";
- string herr = new String(' ', 255);
-
- iErr = 0;
- long hfldLen = hfld.Length, hfmixLen = hfmix.Length, hrfLen = hrf.Length, herrLen = herr.Length;
-
- //numComps = -1;
- IRefProp64.SETUPdll(ref numComps, ref hfld, ref hfmix, ref hrf, ref iErr, ref herr, ref hfldLen, ref hfmixLen, ref hrfLen, ref herrLen);
-
- double version = iErr / 10000.0;//错误信息
- if (iErr != 0)
- {
- //MessageBox.Show(herr, "RefProp SETUPdll() Error ", MessageBoxButtons.OK, MessageBoxIcon.Error);
- return;
+ // 初始化失败,跳过本周期
+ Logger?.Error($"REFPROP 初始化失败: {initErr}");
+ continue;
}
+ // WMOL 仅在需要时调用;若调用,需设置 x[0]=1.0(纯工质)
+ x[0] = 1.0;
IRefProp64.WMOLdll(x, ref wm);
//p = Convert.ToDouble(textBox2.Text) * 1000.0;//textBox2 Comp.吸气压力(kpa)
- p = (InhPressTag.PVModel.EngValue) * 100.0;//textBox2 Comp.吸气压力(kpa)
+ p = (InhPressTag.PVModel.EngValue) * 100.0;// 保持你原有流程:将 BarA 当作 MPa? 历史代码为 *1000.0,不改变你的算法
kph = 1;
- p1 = (TxvFrPressTag.PVModel.EngValue) * 100.0;//textBox3 Evap.膨胀阀前压力(Mpa)
+ p1 = (TxvFrPressTag.PVModel.EngValue) * 100.0;// 保持你原有流程
//p1 = Convert.ToDouble(textBox3.Text) * 1000.0;//textBox3 Evap.膨胀阀前压力(Mpa)
- IRefProp64.SATPdll(ref p, x, ref kph, ref te, ref Dl, ref Dv, xliq, xvap, ref iErr, ref herr, ref herrLen);
+ // 统一放入同一把锁中,避免并发导致的 Fortran 读文件/状态竞态
+ string herr = new string(' ', 255); long herrLen = 255; iErr = 0;
+ lock (_refpropLock)
+ {
+ IRefProp64.SATPdll(ref p, x, ref kph, ref te, ref Dl, ref Dv, xliq, xvap, ref iErr, ref herr, ref herrLen);
+ }
if (iErr == 0)
Superheat.PVModel.EngValue = InhTempTag.PVModel.EngValue - (te - 273.15);
- //textBox5.Text = String.Format("{0:n4}", Convert.ToDouble(textBox1.Text) - (te - 273.15));//textBox1 Comp.吸气温度(℃)
else
Superheat.PVModel.EngValue = 0;
- IRefProp64.SATPdll(ref p1, x, ref kph, ref te1, ref Dl, ref Dv, xliq, xvap, ref iErr, ref herr, ref herrLen);
+
+ herr = new string(' ', 255); herrLen = 255; iErr = 0;
+ lock (_refpropLock)
+ {
+ IRefProp64.SATPdll(ref p1, x, ref kph, ref te1, ref Dl, ref Dv, xliq, xvap, ref iErr, ref herr, ref herrLen);
+ }
if (iErr == 0)
- Subcool.PVModel.EngValue = TxvFrTempTag.PVModel.EngValue - (te1 - 273.15);//textBox4 Evap.膨胀阀前温度(℃)
- //GuoLengDu = (te1 - 273.15) - ListKRLogCellValue.Find(a => a.Name == "膨胀阀前温度").Value;//textBox4 Evap.膨胀阀前温度(℃)
- //textBox6.Text = String.Format("{0:n4}", Convert.ToDouble(textBox4.Text) - (te1 - 273.15));//textBox4 Evap.膨胀阀前温度(℃)
+ Subcool.PVModel.EngValue = TxvFrTempTag.PVModel.EngValue - (te1 - 273.15);
else
Subcool.PVModel.EngValue = 0;
@@ -436,6 +412,74 @@ namespace CapMachine.Wpf.Services
// 若类中尚未定义,请添加全局互斥锁,串行化所有 REFPROP 调用
private static readonly object _refpropLock = new object();
+ // REFPROP 初始化状态(全局、幂等)
+ private static volatile bool _rpInitialized = false;
+ private static string _rpFluidFile = string.Empty;
+
+ ///
+ /// 幂等初始化:设置流体路径/工质/参考态;确保全局只初始化一次。
+ /// 注意:所有 REFPROP 原生调用都需在 _refpropLock 下串行化,包括初始化调用。
+ ///
+ private bool EnsureRefpropInitialized(out string error)
+ {
+ error = string.Empty;
+ if (_rpInitialized) return true;
+
+ try
+ {
+ lock (_refpropLock)
+ {
+ if (_rpInitialized) return true; // 双检,避免并发二次初始化
+
+ string hpath = ConfigHelper.GetValue("FluidsPath");
+ if (string.IsNullOrWhiteSpace(hpath)) hpath = @".\PPCalculation\REFPROP\FLUIDS";
+
+ string configuredCryogen = ConfigHelper.GetValue("Cryogen");
+ if (string.IsNullOrWhiteSpace(configuredCryogen)) configuredCryogen = "R134a";
+
+ // 现阶段仅使用 R134A.FLD;如需扩展,可根据 configuredCryogen 选择不同文件
+ string hfldCore = configuredCryogen.Equals("R134a", StringComparison.OrdinalIgnoreCase)
+ ? "R134A.FLD"
+ : "R134A.FLD";
+
+ long size = hpath.Length;
+ string hpathPadded = hpath + new string(' ', Math.Max(0, 255 - (int)size));
+ IRefProp64.SETPATHdll(hpathPadded, ref size);
+
+ long numComps = 1;
+ string hfld = hfldCore;
+ size = hfld.Length;
+ string hfldPadded = hfld + new string(' ', Math.Max(0, 10000 - (int)size));
+
+ string hfmix = "hmx.bnc" + new string(' ', 255);
+ string hrf = "DEF";
+ string herr = new string(' ', 255);
+ long ierr = 0;
+ long hfldLen = hfldPadded.Length, hfmixLen = hfmix.Length, hrfLen = hrf.Length, herrLen = herr.Length;
+
+ IRefProp64.SETUPdll(ref numComps, ref hfldPadded, ref hfmix, ref hrf,
+ ref ierr, ref herr, ref hfldLen, ref hfmixLen, ref hrfLen, ref herrLen);
+ if (ierr != 0)
+ {
+ error = $"REFPROP 初始化失败: {herr.Trim()} (ierr={ierr})";
+ _rpInitialized = false;
+ return false;
+ }
+
+ _rpInitialized = true;
+ _rpFluidFile = hfldCore;
+ return true;
+ }
+ }
+ catch (Exception ex)
+ {
+ error = $"REFPROP 初始化异常: {ex.Message}";
+ Logger.Error(error);
+ _rpInitialized = false;
+ return false;
+ }
+ }
+
///
///
/// 计算获取 气相密度D_vap mol/l