public void Start(IConnectionParameters connectionParameters)
        {
            _cancellationTokenSource = new CancellationTokenSource();

            _deviceEventReceiver = _deviceEventReceiverFactory.Create(connectionParameters);
            _deviceEventReceiver.EventReceived += DeviceEventReceiverOnEventReceived;

            Task.Run(() => ReceiveEventsAsync(_deviceEventReceiver, _cancellationTokenSource.Token));
        }
        public void Stop()
        {
            if (_deviceEventReceiver == null)
            {
                return;
            }

            _cancellationTokenSource.Cancel();
            _deviceEventReceiver.EventReceived -= DeviceEventReceiverOnEventReceived;
            _deviceEventReceiver = null;
        }
        public void Start_WhenConnectingStateChanges_StateChangedHandlerInvoked()
        {
            IDeviceEventReceiver        eventReceiverFake        = CreateDeviceEventReceiverFake(null);
            IDeviceEventReceiverFactory eventReceiverFactoryFake = CreateDeviceEventReceiverFactoryFake(eventReceiverFake);

            var autoResetEvent = new AutoResetEvent(false);
            var model          = new MainWindowModel(eventReceiverFactoryFake);

            model.ConnectionStateChanged += (sender, @event) => autoResetEvent.Set();
            model.Start(CreateConnectionParametersFake());

            Assert.IsTrue(autoResetEvent.WaitOne(TestWaitTimeoutMs));
        }
        public void Stop_ConnectionEstablishedThenAborted_StoppedEventHandlerInvoked()
        {
            IDeviceEventReceiver        eventReceiverFake        = CreateDeviceEventReceiverFake(null);
            IDeviceEventReceiverFactory eventReceiverFactoryFake = CreateDeviceEventReceiverFactoryFake(eventReceiverFake);

            var autoResetEvent = new AutoResetEvent(false);
            var model          = new MainWindowModel(eventReceiverFactoryFake);

            model.Stopped += (sender, args) => autoResetEvent.Set();
            model.Start(CreateConnectionParametersFake());
            Thread.Sleep(500);
            model.Stop();

            Assert.IsTrue(autoResetEvent.WaitOne(TestWaitTimeoutMs));
        }
        public void Start_ConnectionEstablishedAndEventIsReceived_EventReceivedHandlerInvoked()
        {
            var patternEvent = new DeviceEvent("test");
            IDeviceEventReceiver        eventReceiverFake        = CreateDeviceEventReceiverFake(patternEvent);
            IDeviceEventReceiverFactory eventReceiverFactoryFake = CreateDeviceEventReceiverFactoryFake(eventReceiverFake);

            var         autoResetEvent = new AutoResetEvent(false);
            DeviceEvent currentEvent   = null;
            var         model          = new MainWindowModel(eventReceiverFactoryFake);

            model.EventReceived += (sender, @event) =>
            {
                currentEvent = @event;
                autoResetEvent.Set();
            };
            model.Start(CreateConnectionParametersFake());

            Assert.IsTrue(autoResetEvent.WaitOne(TestWaitTimeoutMs));
            Assert.AreSame(patternEvent, currentEvent);
        }
        private async void ReceiveEventsAsync(IDeviceEventReceiver deviceEventReceiver, CancellationToken token)
        {
            while (!token.IsCancellationRequested)
            {
                try
                {
                    OnStateChanged(new ConnectionStateInfo(
                                       $"Connecting to {deviceEventReceiver.ConnectionParameters.ConnectionUri}..."));

                    await deviceEventReceiver.ConnectAsync(token).ConfigureAwait(false);

                    OnStateChanged(new ConnectionStateInfo("Connection is established. Receiving..."));

                    await deviceEventReceiver.ReceiveAsync(token);
                }
                catch (OperationCanceledException)
                {
                    break;
                }
                catch (OutOfMemoryException)
                {
                    throw;
                }
                catch (Exception e)
                {
                    OnStateChanged(new ConnectionStateInfo($"Connection error: {e.Message}"));
                }

                try
                {
                    await Task.Delay(ReconnectionDelay, token);
                }
                catch (OperationCanceledException)
                {
                    break;
                }
            }

            Stopped?.Invoke(this, EventArgs.Empty);
        }
        private static IDeviceEventReceiverFactory CreateDeviceEventReceiverFactoryFake(IDeviceEventReceiver eventReceiver)
        {
            var factoryFake = new Mock <IDeviceEventReceiverFactory>();

            factoryFake.Setup(x => x.Create(It.IsNotNull <IConnectionParameters>()))
            .Returns(eventReceiver);

            return(factoryFake.Object);
        }