From 96680fd4c62752061d9ce17f18caadba130f2aec Mon Sep 17 00:00:00 2001 From: hsc Date: Wed, 16 Sep 2026 09:01:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=9B=91=E6=8E=A7bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MonitorModule/ViewModels/MonitorViewModel.cs | 4 +- MonitorModule/ViewModels/RecordViewModel.cs | 4 +- .../GlobalVariable/HardwareDataBroadcaster.cs | 42 ++++++++++++++----- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/MonitorModule/ViewModels/MonitorViewModel.cs b/MonitorModule/ViewModels/MonitorViewModel.cs index 4843448..e3fefb8 100644 --- a/MonitorModule/ViewModels/MonitorViewModel.cs +++ b/MonitorModule/ViewModels/MonitorViewModel.cs @@ -433,7 +433,9 @@ namespace MonitorModule.ViewModels .Where(m => { if (m.GetCustomAttribute() == null) return false; - if (m.ReturnType != typeof(Task)) return false; + // 同时支持 Task 和 Task 返回类型 + var rt = m.ReturnType; + if (rt != typeof(Task) && rt != typeof(Task)) return false; var parms = m.GetParameters(); return parms.Length == 0 || (parms.Length == 1 && parms[0].ParameterType == typeof(CancellationToken)); diff --git a/MonitorModule/ViewModels/RecordViewModel.cs b/MonitorModule/ViewModels/RecordViewModel.cs index bfb575f..358b7cc 100644 --- a/MonitorModule/ViewModels/RecordViewModel.cs +++ b/MonitorModule/ViewModels/RecordViewModel.cs @@ -233,7 +233,9 @@ namespace MonitorModule.ViewModels .Where(m => { if (m.GetCustomAttribute() == null) return false; - if (m.ReturnType != typeof(Task)) return false; + // 同时支持 Task 和 Task 返回类型 + var rt = m.ReturnType; + if (rt != typeof(Task) && rt != typeof(Task)) return false; var parms = m.GetParameters(); return parms.Length == 0 || (parms.Length == 1 && parms[0].ParameterType == typeof(CancellationToken)); diff --git a/UIShare/GlobalVariable/HardwareDataBroadcaster.cs b/UIShare/GlobalVariable/HardwareDataBroadcaster.cs index 2380403..12a836c 100644 --- a/UIShare/GlobalVariable/HardwareDataBroadcaster.cs +++ b/UIShare/GlobalVariable/HardwareDataBroadcaster.cs @@ -33,12 +33,12 @@ namespace UIShare.GlobalVariable /// /// 已注册的采样项:(Fingerprint, MethodName, 编译后的委托, DeviceInstance) - /// 委托签名统一为 Func<object, CancellationToken, Task<string>> + /// 委托签名统一为 Func<object, CancellationToken, Task<double>> /// - 第一个参数 = 设备实例(open delegate 风格,编译时已做类型转换) /// - 第二个参数 = CancellationToken(无参方法会忽略它) - /// - 返回值 = Task<string> + /// - 返回值 = Task<double>(Task<string> 方法自动 TryParse 为 double) /// - private readonly List<(string Fingerprint, string MethodName, Func> Invoker, object Device)> _registeredMethods = new(); + private readonly List<(string Fingerprint, string MethodName, Func> Invoker, object Device)> _registeredMethods = new(); private CancellationTokenSource? _cts; private bool _disposed; @@ -76,11 +76,13 @@ namespace UIShare.GlobalVariable /// /// 将 MethodInfo 编译为强类型委托,后续调用零反射开销。 - /// 统一签名为 Func<object, CancellationToken, Task<string>>: + /// 统一签名为 Func<object, CancellationToken, Task<double>>: + /// - Task<double> 方法:直接返回 double 值 + /// - Task<string> 方法:自动 TryParse 为 double /// - 无参方法:忽略 CancellationToken /// - 带 CancellationToken 方法:直接透传 /// - private static Func> BuildInvoker(MethodInfo method) + private static Func> BuildInvoker(MethodInfo method) { var deviceParam = Expression.Parameter(typeof(object), "device"); var ctParam = Expression.Parameter(typeof(CancellationToken), "ct"); @@ -96,8 +98,24 @@ namespace UIShare.GlobalVariable var call = Expression.Call(castDevice, method, callArgs); - return Expression.Lambda>>( - call, deviceParam, ctParam).Compile(); + if (method.ReturnType == typeof(Task)) + { + // Task 方法:直接返回 + return Expression.Lambda>>( + call, deviceParam, ctParam).Compile(); + } + else + { + // Task 方法:await 后 TryParse 为 double + return async (device, ct) => + { + // 通过 MethodInfo.Invoke 调用(仅 Task 路径,性能可接受) + var task = (Task)method.Invoke(device, + parms.Length == 1 ? new object[] { ct } : Array.Empty())!; + string raw = await task.ConfigureAwait(false); + return double.TryParse(raw, out double v) ? v : double.NaN; + }; + } } /// @@ -126,7 +144,9 @@ namespace UIShare.GlobalVariable .Where(m => { if (m.GetCustomAttribute() == null) return false; - if (m.ReturnType != typeof(Task)) return false; + // 同时支持 Task 和 Task 返回类型 + var rt = m.ReturnType; + if (rt != typeof(Task) && rt != typeof(Task)) return false; var parms = m.GetParameters(); return parms.Length == 0 || (parms.Length == 1 && parms[0].ParameterType == typeof(CancellationToken)); @@ -184,10 +204,10 @@ namespace UIShare.GlobalVariable { try { - // 直接委托调用,零反射开销 - string raw = await entry.Invoker(entry.Device, token).ConfigureAwait(false); + // 直接委托调用,零反射开销(Task 路径)或自动 TryParse(Task 路径) + double value = await entry.Invoker(entry.Device, token).ConfigureAwait(false); - if (!double.TryParse(raw, out double value)) return; + if (double.IsNaN(value)) return; // 采样成功,重置失败计数 _failureCounts.TryRemove(channelKey, out _);