diff --git a/src/client/DCSInsight/Communication/TCPClientHandler.cs b/src/client/DCSInsight/Communication/TCPClientHandler.cs index 480983d..cce29d1 100644 --- a/src/client/DCSInsight/Communication/TCPClientHandler.cs +++ b/src/client/DCSInsight/Communication/TCPClientHandler.cs @@ -29,6 +29,7 @@ internal class TCPClientHandler : IDisposable, ICommandListener private int _metaDataPollCounter; public bool LogJSON { get; set; } private string _currentMessage = ""; + private volatile bool _responseReceived; public TCPClientHandler(string host, string port) { @@ -48,6 +49,7 @@ public void Dispose() private async void ClientThread() { ICEventHandler.SendConnectionStatus(_isRunning); + _responseReceived = true; while (_isRunning) { try @@ -81,12 +83,13 @@ private async void ClientThread() Thread.Sleep(1000); } - if (_asyncCommandsChannel.Reader.Count > 0) + if (_asyncCommandsChannel.Reader.Count > 0 && _responseReceived) { var cts = new CancellationTokenSource(100); var dcsApi = await _asyncCommandsChannel.Reader.ReadAsync(cts.Token); if (LogJSON) Logger.Info(JsonConvert.SerializeObject(dcsApi, Formatting.Indented)); _tcpClient.GetStream().Write(Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(dcsApi) + "\n")); + _responseReceived = false; } if (_tcpClient.Available <= 0) continue; @@ -101,6 +104,7 @@ private async void ClientThread() catch (SocketException ex) { Logger.Error(ex); + break; } } @@ -124,6 +128,7 @@ private void HandleMessage(string str) var dcsApi = JsonConvert.DeserializeObject(_currentMessage + str); _currentMessage = ""; ICEventHandler.SendData(dcsApi); + _responseReceived = true; } else { @@ -142,6 +147,7 @@ private void HandleAPIMessage(string str) { var dcsAPIList = JsonConvert.DeserializeObject>(str); ICEventHandler.SendData(dcsAPIList); + _responseReceived = true; _apiListReceived = true; } catch (Exception ex) diff --git a/src/client/DCSInsight/DCSInsight.csproj b/src/client/DCSInsight/DCSInsight.csproj index 4e239c2..dec4952 100644 --- a/src/client/DCSInsight/DCSInsight.csproj +++ b/src/client/DCSInsight/DCSInsight.csproj @@ -6,7 +6,7 @@ true dcs-insight 1.0.0 - 1.8.2 + 1.8.3 Images\Magnifier_icon.ico diff --git a/src/client/DCSInsight/DCSInsight.sln.DotSettings b/src/client/DCSInsight/DCSInsight.sln.DotSettings index d366ca5..d2b28ae 100644 --- a/src/client/DCSInsight/DCSInsight.sln.DotSettings +++ b/src/client/DCSInsight/DCSInsight.sln.DotSettings @@ -8,6 +8,7 @@ TCP UI API + True True True True diff --git a/src/client/DCSInsight/MainWindow.xaml.cs b/src/client/DCSInsight/MainWindow.xaml.cs index 01324a7..a0b2b24 100644 --- a/src/client/DCSInsight/MainWindow.xaml.cs +++ b/src/client/DCSInsight/MainWindow.xaml.cs @@ -140,6 +140,13 @@ public void ConnectionStatus(ConnectionEventArgs args) try { _isConnected = args.IsConnected; + if (!_isConnected) + { + Dispatcher?.BeginInvoke((Action)(Disconnect)); + Dispatcher?.BeginInvoke((Action)(SetFormState)); + return; + } + Dispatcher?.BeginInvoke((Action)(() => SetConnectionStatus(args.IsConnected))); Dispatcher?.BeginInvoke((Action)(SetFormState)); ; } diff --git a/src/client/DCSInsight/UserControls/UserControlAPI.xaml.cs b/src/client/DCSInsight/UserControls/UserControlAPI.xaml.cs index fe8feaa..fa3c675 100644 --- a/src/client/DCSInsight/UserControls/UserControlAPI.xaml.cs +++ b/src/client/DCSInsight/UserControls/UserControlAPI.xaml.cs @@ -175,7 +175,6 @@ protected override void BuildUI() VerticalAlignment = VerticalAlignment.Center }; ComboBoxPollTimes.DataContextChanged += ComboBoxPollTimes_OnDataContextChanged; - ComboBoxPollTimes.Items.Add(50); ComboBoxPollTimes.Items.Add(100); ComboBoxPollTimes.Items.Add(500); ComboBoxPollTimes.Items.Add(1000); @@ -206,7 +205,8 @@ public override void SetResult(DCSAPI dcsApi) Dispatcher?.BeginInvoke((Action)(() => LabelResult.Content = $"Result ({dcsApi.ResultType})")); var result = dcsApi.ErrorThrown ? dcsApi.ErrorMessage : (string.IsNullOrEmpty(dcsApi.Result) ? "nil" : dcsApi.Result); - + + AutoResetEventPolling.Set(); if (KeepResults) { Dispatcher?.BeginInvoke((Action)(() => TextBoxResult.Text = TextBoxResult.Text.Insert(0, "\n---\n"))); diff --git a/src/client/DCSInsight/UserControls/UserControlAPIBase.cs b/src/client/DCSInsight/UserControls/UserControlAPIBase.cs index 5ea3cb3..2c6f5e4 100644 --- a/src/client/DCSInsight/UserControls/UserControlAPIBase.cs +++ b/src/client/DCSInsight/UserControls/UserControlAPIBase.cs @@ -33,6 +33,8 @@ public abstract partial class UserControlAPIBase : UserControl, IDisposable, IAs protected CheckBox CheckBoxPolling; protected Label LabelPollingInterval; protected ComboBox ComboBoxPollTimes; + protected static readonly AutoResetEvent AutoResetEventPolling = new(false); + public int Id { get; protected set; } protected abstract void BuildUI(); public abstract void SetResult(DCSAPI dcsApi); @@ -50,7 +52,10 @@ protected UserControlAPIBase(DCSAPI dcsAPI, bool isConnected) public void Dispose() { + AutoResetEventPolling.Set(); + AutoResetEventPolling.Set(); PollingTimer?.Dispose(); + AutoResetEventPolling.Dispose(); GC.SuppressFinalize(this); } @@ -58,7 +63,10 @@ public async ValueTask DisposeAsync() { if (PollingTimer != null) { + AutoResetEventPolling.Set(); + AutoResetEventPolling.Set(); await PollingTimer.DisposeAsync(); + AutoResetEventPolling.Dispose(); GC.SuppressFinalize(this); } } @@ -68,6 +76,10 @@ public void SetConnectionStatus(bool connected) try { IsConnected = connected; + if (!IsConnected) + { + PollingTimer.Change(Timeout.Infinite, 10000); + } SetFormState(); } catch (Exception ex) @@ -93,6 +105,7 @@ protected void StartPolling(int milliseconds) try { PollingTimer.Change(milliseconds, milliseconds); + AutoResetEventPolling.Set(); SetFormState(); } catch (Exception ex) @@ -118,6 +131,7 @@ protected void PollingTimerCallback(object state) { try { + AutoResetEventPolling.WaitOne(); if (CanSend) { Dispatcher?.BeginInvoke((Action)(SendCommand)); diff --git a/src/client/DCSInsight/UserControls/UserControlLoSetCommandAPI.xaml.cs b/src/client/DCSInsight/UserControls/UserControlLoSetCommandAPI.xaml.cs index 574f1a1..df6e4f2 100644 --- a/src/client/DCSInsight/UserControls/UserControlLoSetCommandAPI.xaml.cs +++ b/src/client/DCSInsight/UserControls/UserControlLoSetCommandAPI.xaml.cs @@ -233,11 +233,6 @@ protected override void BuildUI() } } - private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e) - { - throw new NotImplementedException(); - } - public override void SetResult(DCSAPI dcsApi) { try @@ -245,6 +240,8 @@ public override void SetResult(DCSAPI dcsApi) Dispatcher?.BeginInvoke((Action)(() => LabelResult.Content = $"Result ({dcsApi.ResultType})")); var result = dcsApi.ErrorThrown ? dcsApi.ErrorMessage : (string.IsNullOrEmpty(dcsApi.Result) ? "nil" : dcsApi.Result); + + AutoResetEventPolling.Set(); if (KeepResults) {