示例#1
0
        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));
                }
            }
        }