private async Task MainLoop() { var cancellationToken = _applicationLifetime.ApplicationStopping; try { while (!cancellationToken.IsCancellationRequested) { var turnOnRequest = await _eventHub.ReceiveTurnOnRequestedMessage(cancellationToken); if (turnOnRequest.RequestedOperationalMode == OperationalMode.Timed) { _relayService.TurnOn(); CancellationTokenSource turnOffRequestAwaitCancellationTokenSource = new CancellationTokenSource(); var turnOffRequestTask = _eventHub.ReceiveTurnOffRequestedMessage ( CancellationTokenSource.CreateLinkedTokenSource ( cancellationToken, turnOffRequestAwaitCancellationTokenSource.Token ).Token ); var desiredTurnOnDurationElapsedTask = Task.Delay(turnOnRequest.DesiredDuration, cancellationToken); var completedTask = await Task.WhenAny(turnOffRequestTask, desiredTurnOnDurationElapsedTask); _relayService.TurnOff(); if (completedTask == desiredTurnOnDurationElapsedTask) { turnOffRequestAwaitCancellationTokenSource.Cancel(); _eventHub.PostTimedTurnOffNotificationMessage(new TimedTurnOffNotificationMessage()); } } if (turnOnRequest.RequestedOperationalMode == OperationalMode.Thermostat) { var turnOffTask = _eventHub.ReceiveTurnOffRequestedMessage(cancellationToken); while (!turnOffTask.IsCompleted) { await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken); var temperatureMeasurement = await _eventHub.ReceiveTemperatureMeasurement(cancellationToken); if (temperatureMeasurement.Temperature < turnOnRequest.DesiredTemperature) { _relayService.TurnOn(); } else { _relayService.TurnOff(); } } _relayService.TurnOff(); } } } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { _logger.LogInformation("Stopped listening for events."); } catch (Exception ex) { _logger.LogError(ex, "Unexpected control failure."); } }