From d2cc3c8c9771c345180eb1dc5f9982e178478468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sim=C3=B5es?= Date: Sun, 4 Feb 2018 12:14:36 +0000 Subject: [PATCH] Work on stability (#113) --- source/USB Test App WPF/MainWindow.xaml.cs | 39 ++++++-- .../PortSerial/EventHandlerForSerialDevice.cs | 9 +- .../WireProtocol/Controller.cs | 7 ++ .../WireProtocol/Engine.cs | 96 +++++++++++++------ 4 files changed, 112 insertions(+), 39 deletions(-) diff --git a/source/USB Test App WPF/MainWindow.xaml.cs b/source/USB Test App WPF/MainWindow.xaml.cs index a50e7bbd..90d8aabe 100644 --- a/source/USB Test App WPF/MainWindow.xaml.cs +++ b/source/USB Test App WPF/MainWindow.xaml.cs @@ -13,6 +13,7 @@ using System.IO; using System.Text; using System.Threading; +using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Threading; @@ -270,25 +271,38 @@ private async void DeployTestButton_Click(object sender, RoutedEventArgs e) List assemblies = new List(4); // test data -// mscorlib v(36500 bytes) -// Windows.Storage.Streams v(6180 bytes) -// Windows.Devices.SerialCommunication v(3172 bytes) -// SerialCommunication v1.0.6578.34099(1180 bytes) -// assemblies to device...total size in bytes is 47032. + // mscorlib v(36500 bytes) + // Windows.Storage.Streams v(6180 bytes) + // Windows.Devices.SerialCommunication v(3172 bytes) + // SerialCommunication v1.0.6578.34099(1180 bytes) + // assemblies to device...total size in bytes is 47032. - assemblies.Add(new byte[36500]); + var p1Size = 36500; + var p2Size = 6180; + var p3Size = 3172; + var p4Size = 1180; + + + assemblies.Add(new byte[p1Size]); assemblies[0][0] = 0x5; assemblies[0][1] = 0x5; - assemblies.Add(new byte[6180]); + assemblies.Add(new byte[p2Size]); assemblies[1][0] = 0x6; assemblies[1][1] = 0x6; - assemblies.Add(new byte[3172]); + assemblies.Add(new byte[p3Size]); assemblies[2][0] = 0x7; assemblies[2][1] = 0x7; - assemblies.Add(new byte[1180]); + assemblies.Add(new byte[p4Size]); assemblies[3][0] = 0x8; assemblies[3][1] = 0x8; + var totalSize = p1Size + p2Size + p3Size + p4Size; + + var largePackets = totalSize / (1024 - 8); + + Debug.WriteLine($">>> Sending : {totalSize} bytes.<<<<"); + Debug.WriteLine($">>> This is {largePackets} 1k packets plus bytes.<<<<"); + try { //// add mscorlib @@ -311,6 +325,13 @@ private async void DeployTestButton_Click(object sender, RoutedEventArgs e) Debug.WriteLine($">>> Deployment result: {result} <<<<"); + + (DataContext as MainViewModel).AvailableDevices[DeviceGrid.SelectedIndex].DebugEngine.RebootDevice(RebootOption.RebootClrOnly); + + Task.Delay(1000).Wait(); + + (DataContext as MainViewModel).AvailableDevices[DeviceGrid.SelectedIndex].GetDeviceInfo(true); + })); } catch diff --git a/source/nanoFramework.Tools.DebugLibrary.Shared/PortSerial/EventHandlerForSerialDevice.cs b/source/nanoFramework.Tools.DebugLibrary.Shared/PortSerial/EventHandlerForSerialDevice.cs index 6f914671..388c820a 100644 --- a/source/nanoFramework.Tools.DebugLibrary.Shared/PortSerial/EventHandlerForSerialDevice.cs +++ b/source/nanoFramework.Tools.DebugLibrary.Shared/PortSerial/EventHandlerForSerialDevice.cs @@ -4,7 +4,9 @@ // using System; +using System.Collections.Generic; using System.Diagnostics; +using System.Threading.Tasks; using Windows.Devices.Enumeration; using Windows.Devices.SerialCommunication; using Windows.Foundation; @@ -262,8 +264,13 @@ private void CloseCurrentlyConnectedDevice() Debug.WriteLine($"Closing device {_deviceInformation?.Id}"); + var tasks = new List(); + tasks.Add(Task.Factory.StartNew(() => _device.Dispose())); + // This closes the handle to the device - _device.Dispose(); + Task.WaitAll(tasks.ToArray(), 2000); + + _device = null; } } diff --git a/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Controller.cs b/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Controller.cs index f153e3de..78abc6fc 100644 --- a/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Controller.cs +++ b/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Controller.cs @@ -130,6 +130,13 @@ private async Task SendRawBufferAsync(byte[] buffer, TimeSpan waiTimeout, internal async Task ReadBufferAsync(byte[] buffer, int offset, int bytesToRead, TimeSpan waitTimeout, CancellationToken cancellationToken) { + // check for cancellation request + if (cancellationToken.IsCancellationRequested) + { + // cancellation requested + return 0; + } + int bytesToReadRequested = bytesToRead; try diff --git a/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Engine.cs b/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Engine.cs index 4910d64d..c0e113e3 100644 --- a/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Engine.cs +++ b/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Engine.cs @@ -245,27 +245,47 @@ public async Task IncomingMessagesListenerAsync() while (!_backgroundProcessorCancellation.IsCancellationRequested && _state.IsRunning) { - await Device.ConnectAsync(); - - try - { - await reassembler.ProcessAsync(_backgroundProcessorCancellation.Token); - } - catch (DeviceNotConnectedException) - { - await Task.Delay(1000); - await Device.ConnectAsync(); - } - catch (Exception ex) + if (await Device.ConnectAsync()) { - if (ex.GetType().Equals(typeof(AggregateException))) + try + { + await reassembler.ProcessAsync(_backgroundProcessorCancellation.Token); + } + catch (DeviceNotConnectedException) { - if (ex.GetBaseException().GetType().Name == typeof(DeviceNotConnectedException).Name) + if (_backgroundProcessorCancellation.IsCancellationRequested || !_state.IsRunning) + { + return; + } + else { await Task.Delay(1000); await Device.ConnectAsync(); } } + catch (Exception ex) + { + if (_backgroundProcessorCancellation.IsCancellationRequested || !_state.IsRunning) + { + return; + } + else + { + + if (ex.GetType().Equals(typeof(AggregateException))) + { + if (ex.GetBaseException().GetType().Name == typeof(DeviceNotConnectedException).Name) + { + await Task.Delay(1000); + await Device.ConnectAsync(); + } + } + else if (ex.HResult == 0x80070006) + { + return; + } + } + } } } } @@ -416,12 +436,34 @@ private IncomingMessage PerformSyncRequest(uint command, uint flags, object payl { OutgoingMessage message = new OutgoingMessage(_controlller.GetNextSequenceId(), CreateConverter(), command, flags, payload); - return PerformRequestAsync(message, _cancellationTokenSource.Token, millisecondsTimeout).Result; + var request = PerformRequestAsync(message, _cancellationTokenSource.Token, millisecondsTimeout); + + try + { + Task.WaitAll(request); + } + catch(AggregateException) + { + return null; + } + + return request.Result; } private IncomingMessage PerformSyncRequest(OutgoingMessage message, int millisecondsTimeout = 5000) { - return PerformRequestAsync(message, _cancellationTokenSource.Token, millisecondsTimeout).Result; + var request = PerformRequestAsync(message, _cancellationTokenSource.Token, millisecondsTimeout); + + try + { + Task.WaitAll(request); + } + catch (AggregateException) + { + return null; + } + + return request.Result; } public Task PerformRequestAsync(OutgoingMessage message, CancellationToken cancellationToken, int millisecondsTimeout = 5000) @@ -434,7 +476,7 @@ public Task PerformRequestAsync(OutgoingMessage message, Cancel // Start a background task that will complete tcs1.Task Task.Factory.StartNew(() => { - var dummy = request.PerformRequestAsync(_controlller); + request.PerformRequestAsync(_controlller).Wait(); }); } catch (Exception ex) @@ -603,7 +645,12 @@ public void StopProcessing() { _backgroundProcessorCancellation.Cancel(); - Task.WaitAll(_backgroundProcessor); + try + { + Task.WaitAll(_backgroundProcessor); + } + catch (AggregateException) { } + _backgroundProcessor = null; } } @@ -1197,16 +1244,7 @@ public Commands.Monitor_OemInfo.Reply GetMonitorOemInfo() Commands.Monitor_WriteMemory cmd = new Commands.Monitor_WriteMemory(); // get packet length, either the maximum allowed size or whatever is still available to TX - // on the maximum packet size: 8 bytes are being subtracted to account for the CRC32 value - // the above seems to be paramount because the WinRT API seems to have issues with USB packets smaller than 64 bytes - int packetLength = Math.Min(1024 - 8, count); - - // sanity check for length because TXing a packet with less than 64 bytes seems to be causing issues - if ((count - packetLength) < 64 && count > 64) - { - // need to adjust this length so that 64 bytes are left for the last packet - packetLength = (count - 64); - } + int packetLength = Math.Min(1024, count); cmd.PrepareForSend(address, buf, position, packetLength); @@ -1350,7 +1388,7 @@ public void RebootDevice(RebootOption option = RebootOption.NormalReboot) { m_evtPing.Reset(); - PerformSyncRequest(Commands.c_Monitor_Reboot, Flags.c_NoCaching, cmd); + IncomingMessage reply = PerformSyncRequest(Commands.c_Monitor_Reboot, Flags.c_NoCaching, cmd); // need to disconnect from the device? if (disconnectRequired)