public virtual void Run(UsbManager usbManager) { if (usbManager == null) { throw new ArgumentNullException(nameof(usbManager)); } if (_isDisposed) { throw new ObjectDisposedException(nameof(PortManager)); } // ReSharper disable once RedundantAssignment bool startRunning = false; lock (_stateLocker) { if (GetCurrentState() != ManagerState.Stopped) { throw new InvalidOperationException("Already running."); } else { _managerState = ManagerState.Running; startRunning = true; } } // ReSharper disable once ConditionIsAlwaysTrueOrFalse if (startRunning) { try { UsbDeviceConnection connection = usbManager.OpenDevice(_port.Driver.Device); if (connection == null) { throw new UsbSerialException("Failed to connect to device."); } _portBuffer = new byte[BufferSize]; _port.Open(connection); _port.SetParameters(BaudRate, DataBits, StopBits, Parity); _runCancellationSource = new CancellationTokenSource(); CancellationToken runCancellationToken = _runCancellationSource.Token; runCancellationToken.Register(() => Log.Info(nameof(PortManager), "Cancellation Requested")); Task.Run(() => { Log.Info(nameof(PortManager), "Running .."); try { bool isRunning; do { ManagerState currentState; lock (_stateLocker) { isRunning = ((currentState = GetCurrentState()) == ManagerState.Running); } if (isRunning) { runCancellationToken.ThrowIfCancellationRequested(); Step(); } else { Log.Info(nameof(PortManager), $"Stopping mState={currentState}"); } } while (isRunning); } catch (OperationCanceledException) { throw; } catch (Exception e) { Log.Warn(nameof(PortManager), $"Task ending due to exception: {e.Message}", e); ErrorReceived.RaiseEvent(this, new UnhandledExceptionEventArgs(e, false)); } finally { _port.Close(); _portBuffer = null; lock (_stateLocker) { _managerState = ManagerState.Stopped; Log.Info(nameof(PortManager), "Stopped."); } } }, runCancellationToken); } catch (Exception e) { lock (_stateLocker) { _managerState = ManagerState.Stopped; Log.Info(nameof(PortManager), "Stopped."); } Log.Warn(nameof(PortManager), $"Run ending due to exception: {e.Message}", e); ErrorReceived.RaiseEvent(this, new UnhandledExceptionEventArgs(e, false)); } } }