diff --git a/SuperCom/Core/Config/AdvancedSendSettings.cs b/SuperCom/Core/Config/AdvancedSendSettings.cs index a7e3383..6803f2e 100644 --- a/SuperCom/Core/Config/AdvancedSendSettings.cs +++ b/SuperCom/Core/Config/AdvancedSendSettings.cs @@ -7,6 +7,11 @@ public class AdvancedSendSettings : AbstractConfig { public const double DEFAULT_WINDOW_OPACITY = 0.5; public const double DEFAULT_LOG_OPACITY = 0.8; + + /// + /// 发送延时的误差补偿 + /// + public const long DEFAULT_SEND_COMPENSATION = 30; private AdvancedSendSettings() : base(ConfigManager.SQLITE_DATA_PATH, $"WindowConfig.AdvancedSendSettings") { Width = SystemParameters.WorkArea.Width * 0.7; @@ -14,6 +19,9 @@ private AdvancedSendSettings() : base(ConfigManager.SQLITE_DATA_PATH, $"WindowCo FirstRun = true; LogOpacity = DEFAULT_LOG_OPACITY; WindowOpacity = DEFAULT_WINDOW_OPACITY; + + EnableSendCompensation = false; + SendCompensation = DEFAULT_SEND_COMPENSATION; } private static AdvancedSendSettings _instance = null; @@ -40,6 +48,30 @@ public static AdvancedSendSettings CreateInstance() public bool LogAutoWrap { get; set; } public double LogOpacity { get; set; } + private bool _EnableSendCompensation; + + /// + /// 是否开启误差补偿 + /// + public bool EnableSendCompensation { + get { return _EnableSendCompensation; } + set { + _EnableSendCompensation = value; + RaisePropertyChanged(); + } + } + + private long _SendCompensation; + /// + /// 误差补偿大小 + /// + public long SendCompensation { + get { return _SendCompensation; } + set { + _SendCompensation = value; + RaisePropertyChanged(); + } + } } } diff --git a/SuperCom/Core/Entity/AdvancedSend.cs b/SuperCom/Core/Entity/AdvancedSend.cs index 174c6e4..7be32d1 100644 --- a/SuperCom/Core/Entity/AdvancedSend.cs +++ b/SuperCom/Core/Entity/AdvancedSend.cs @@ -170,7 +170,7 @@ public static void InitSqlite() private async Task AsyncSendCommand(int idx, PortTabItem portTabItem, SendCommand command, AdvancedSend advancedSend) { bool success = false; - await App.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)delegate { + await App.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)delegate { string value = command.Command; success = portTabItem.SendCommand(value, true); if (!success) { @@ -184,12 +184,39 @@ await App.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action) return success; } + private async Task CmdDelay(int delay) + { + //if (command.Delay > 0) { + // int delay = 10; + // for (int i = 1; i <= command.Delay; i += delay) { + // if (!portTabItem.RunningCommands) + // break; + // await Task.Delay(delay); + // advancedSend.CommandList[idx].StatusText = $"{command.Delay - i} ms"; + // } + // advancedSend.CommandList[idx].StatusText = "0 ms"; + //} + + int time = delay; + if (ConfigManager.AdvancedSendSettings.EnableSendCompensation) { + time -= (int)ConfigManager.AdvancedSendSettings.SendCompensation; + } + + if (time < 0) + return true; + + // Task.Delay 在 window 系统上会有 15 ms 的误差 + // 参考:https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.delay?view=netframework-4.7.2&redirectedfrom=MSDN#System_Threading_Tasks_Task_Delay_System_Int32 + await Task.Delay(time); + return true; + } + /// /// 发送命令的任务 /// - /// - /// - /// + /// 需要发送的命令集合 + /// 指定发送串口 + /// 发送状态回调函数 public void BeginSendCommands(AdvancedSend advancedSend, PortTabItem portTabItem, Action onSetRunningStatus) { if (advancedSend == null || string.IsNullOrEmpty(advancedSend.Commands) || portTabItem == null) @@ -205,7 +232,6 @@ public void BeginSendCommands(AdvancedSend advancedSend, PortTabItem portTabItem return; } portTabItem.RunningCommands = true; - onSetRunningStatus?.Invoke(true); Task.Run(async () => { int idx = 0; @@ -218,16 +244,7 @@ public void BeginSendCommands(AdvancedSend advancedSend, PortTabItem portTabItem if (!success) break; advancedSend.CommandList[idx].Status = RunningStatus.WaitingDelay; - if (command.Delay > 0) { - int delay = 10; - for (int i = 1; i <= command.Delay; i += delay) { - if (!portTabItem.RunningCommands) - break; - await Task.Delay(delay); - advancedSend.CommandList[idx].StatusText = $"{command.Delay - i} ms"; - } - advancedSend.CommandList[idx].StatusText = "0 ms"; - } + await CmdDelay(command.Delay); advancedSend.CommandList[idx].Status = RunningStatus.WaitingToRun; idx++; if (idx >= advancedSend.CommandList.Count) { diff --git a/SuperCom/MainWindow.xaml.cs b/SuperCom/MainWindow.xaml.cs index fb1a8c1..7a41a6f 100644 --- a/SuperCom/MainWindow.xaml.cs +++ b/SuperCom/MainWindow.xaml.cs @@ -1846,9 +1846,14 @@ private void StartSendCommands(object sender, RoutedEventArgs e) PortTabItem portTabItem = vieModel.PortTabItems.FirstOrDefault(arg => arg.Name.Equals(portName)); if (advancedSend != null) { Logger.Info($"start run command: {advancedSend.ProjectName}"); - advancedSend.BeginSendCommands(advancedSend, portTabItem, (status) => { - SetRunningStatus(button, status); - }); + try { + advancedSend.BeginSendCommands(advancedSend, portTabItem, (status) => { + SetRunningStatus(button, status); + }); + } catch (Exception ex) { + Logger.Error(ex); + MessageCard.Error(ex.Message); + } } } } @@ -2223,7 +2228,7 @@ private void EditCommandCancel(object sender, RoutedEventArgs e) - + private void OpenShortCut(object sender, RoutedEventArgs e) { if (window_ShortCut != null) diff --git a/SuperCom/Windows/Window_AdvancedSend.xaml b/SuperCom/Windows/Window_AdvancedSend.xaml index f2e1072..fe7cca7 100644 --- a/SuperCom/Windows/Window_AdvancedSend.xaml +++ b/SuperCom/Windows/Window_AdvancedSend.xaml @@ -3,6 +3,7 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit" + xmlns:config="clr-namespace:SuperCom.Config" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:super="https://github.com/SuperStudio/SuperControls" @@ -394,6 +395,28 @@ Value="{Binding WindowOpacity, Mode=OneWay}" /> + + + + + + @@ -534,8 +557,17 @@ + + + + + +