private async Task ApplySetup( string socketAdress, string liftSetupText, string propSetupText, string servoSetupText, string liftPulsesRatiosText, string propPulsesRatiosText, string servoPulseCorrectionText, string boostSetup) { var a = _setupDialog.SocketAddress.Trim().Split(':'); if (a.Length == 2) { try { this._connection.Host = new HostName(a[0]); this._connection.Port = a[1]; } catch (Exception ex) { setupAckTextBlock.Text = String.Empty; exceptionTextBlock.Text = $"{DateTimeOffset.Now} {ex.Message}"; return; } this._connection.Socket = null; } if (!UpdateSetupPacket(liftSetupText, propSetupText, servoSetupText, liftPulsesRatiosText, propPulsesRatiosText, servoPulseCorrectionText, boostSetup)) { return; } await _semaphoreSlim.WaitAsync(); try { HovercraftRequestResult response = null; string exceptionMessage = null; response = _setupRecycledResult; _setupRecycledResult.Recycle(); _setupAckText.Clear(); try { await SendHovercraftData(_connection, _setupPacket, response); } catch (Exception ex) { exceptionMessage = $"{DateTimeOffset.Now} {ex.Message}" + Environment.NewLine; } if (ReferenceEquals(exceptionMessage, null) && !ReferenceEquals(response, null) && ReferenceEquals(response.Exception, null)) { if (response.AckResponseLength > 0) { _setupAckText.Append(response.AckResponseBuffer, 0, response.AckResponseLength); } setupAckTextBlock.Text = _setupAckText.ToString(); exceptionTextBlock.Text = String.Empty; return; } if (response.AckResponseLength > 0) { _setupAckText.Append(response.AckResponseBuffer, 0, response.AckResponseLength); } setupAckTextBlock.Text = _setupAckText.ToString(); _sbSetup.Clear(); _sbSetup.Append(exceptionMessage ?? String.Empty); _sbSetup.Append(!ReferenceEquals(response, null) ? (response.Exception ?? String.Empty) : String.Empty); exceptionTextBlock.Text = _sbSetup.ToString(); } finally { _ackCounterStopwatch.Restart(); _semaphoreSlim.Release(); } }
private async static Task SendHovercraftData(Connection connection, byte[] data, HovercraftRequestResult result) { StreamSocket socket = null; Stream outputStream = null; Stream inputStream = null; try { if (connection.Socket == null) { socket = new StreamSocket(); connection.Socket = socket; await socket.ConnectAsync(connection.Host, connection.Port); } socket = connection.Socket; //Write data outputStream = socket.OutputStream.AsStreamForWrite(); var writer = new BinaryWriter(outputStream); writer.Write(data); writer.Flush(); inputStream = socket.InputStream.AsStreamForRead(); var reader = new StreamReader(inputStream); //result.AckResponse = await reader.ReadLineAsync(); result.AckResponseLength = await reader.ReadAsync(result.AckResponseBuffer, 0, result.AckResponseBuffer.Length); //j'enleve le CRLF a la main car je ne veux pas toucher au code du ESP32 pour ne pas perturber l'appli de Marc if (result.AckResponseLength > 2) { if (result.AckResponseBuffer[result.AckResponseLength - 2] == 13 && result.AckResponseBuffer[result.AckResponseLength - 1] == 10) { result.AckResponseBuffer[result.AckResponseLength - 2] = (char)0x00; result.AckResponseBuffer[result.AckResponseLength - 1] = (char)0x00; result.AckResponseLength = result.AckResponseLength - 2; } } } catch (Exception e) { result.Exception = $"{DateTimeOffset.Now} {e.GetType().Name} : {e.Message}"; if (!ReferenceEquals(socket, null)) { try { try { if (!ReferenceEquals(outputStream, null)) { outputStream.Dispose(); } } catch (Exception outputStreamDisposeException) { result.Exception += $@" {DateTimeOffset.Now} outputStream.Dispose() {outputStreamDisposeException.GetType().Name} : {outputStreamDisposeException.Message}"; } try { if (!ReferenceEquals(inputStream, null)) { inputStream.Dispose(); } } catch (Exception inputStreamDisposeException) { result.Exception += $@" {DateTimeOffset.Now} inputStream.Dispose() {inputStreamDisposeException.GetType().Name} : {inputStreamDisposeException.Message}"; } socket.Dispose(); } catch (Exception disposeException) { result.Exception += $@" {DateTimeOffset.Now} socket.Dispose() {disposeException.GetType().Name} : {disposeException.Message}"; } finally { connection.Socket = null; } } } }
private async Task SendControl() { bool forceGC = false; try { if (!await _semaphoreSlim.WaitAsync(0)) { return; } HovercraftRequestResult response = null; string perfText = null; SolidColorBrush perfTextForeground = null; string exceptionText = null; _controlAckText.Clear(); try { _controlPacket[0] = _enabledValue; _controlPacket[1] = _liftValue; _controlPacket[2] = _propulsionValue; _controlPacket[3] = _directionValue; _controlPacket[4] = _isBoostPressed ? (byte)1 : (byte)0; _controlPacket[5] = _isDirectionByLiftPressed ? (byte)1 : (byte)0; response = _controlRecycledResult; _controlRecycledResult.Recycle(); string exceptionMessage = null; try { await SendHovercraftData(_connection, _controlPacket, _controlRecycledResult); } catch (Exception ex) { exceptionMessage = $"{DateTimeOffset.Now} {ex.Message}" + Environment.NewLine; } if (!ReferenceEquals(response, null) && ReferenceEquals(response.Exception, null)) { Interlocked.Increment(ref _lastSecAckCounter); var elapsedMs = _ackCounterStopwatch.ElapsedMilliseconds; if (elapsedMs >= 1000) { long perSec = (_lastSecAckCounter / (elapsedMs / 1000)); bool shouldBeGreen = perSec > 20; perfText = $"{perSec}/sec"; if (_lastBrushWasGreen == null || _lastBrushWasGreen == shouldBeGreen) { perfTextForeground = shouldBeGreen ? _lightGreenBrush : _tomatoBrush; } _lastBrushWasGreen = shouldBeGreen; Interlocked.Exchange(ref _lastSecAckCounter, 0); _ackCounterStopwatch.Restart(); //je tente de lisser l'exec du garbage collector pour diluer/minimiser les lags forceGC = true; } } if (ReferenceEquals(exceptionMessage, null) && !ReferenceEquals(response, null) && ReferenceEquals(response.Exception, null)) { if (response.AckResponseLength > 0) { _controlAckText.Append(response.AckResponseBuffer, 0, response.AckResponseLength); } } else { if (!ReferenceEquals(response, null) && response.AckResponseLength > 0) { _controlAckText.Append(response.AckResponseBuffer, 0, response.AckResponseLength); } _sbControl.Clear(); _sbControl.Append(exceptionMessage ?? String.Empty); _sbControl.Append(!ReferenceEquals(response, null) ? (response.Exception ?? String.Empty) : String.Empty); exceptionText = _sbControl.ToString(); } bool shouldRefreshAckText = false; var lastControlElapsed = _lastControlStopwatch.ElapsedMilliseconds; if (lastControlElapsed > 100) //100ms = 10Hz //40ms = 25Hz { shouldRefreshAckText = true; _lastControlStopwatch.Restart(); } //On touche à l'UI avec parcimonie :p if (exceptionText != null || shouldRefreshAckText || perfText != null) { await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, () => { if (perfText != null) { perfTextBlock.Text = perfText; } ; if (perfTextForeground != null) { perfTextBlock.Foreground = perfTextForeground; } ; controlAckTextBlock.Text = _controlAckText.ToString(); exceptionTextBlock.Text = exceptionText ?? ""; }); } } finally { _semaphoreSlim.Release(); } } finally { if (forceGC) { GC.Collect(0, GCCollectionMode.Forced); } } }