private async Task <Twin> RoundTripTwinMessageAsync( AmqpTwinMessageType amqpTwinMessageType, TwinCollection reportedProperties, CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, cancellationToken, nameof(RoundTripTwinMessageAsync)); } string correlationId = amqpTwinMessageType + Guid.NewGuid().ToString(); Twin response = null; try { cancellationToken.ThrowIfCancellationRequested(); var taskCompletionSource = new TaskCompletionSource <Twin>(); _twinResponseCompletions[correlationId] = taskCompletionSource; using var ctb = new CancellationTokenBundle(_operationTimeout, cancellationToken); await _amqpUnit.SendTwinMessageAsync(amqpTwinMessageType, correlationId, reportedProperties, ctb.Token).ConfigureAwait(false); Task <Twin> receivingTask = taskCompletionSource.Task; if (await Task .WhenAny(receivingTask, Task.Delay(TimeSpan.FromSeconds(ResponseTimeoutInSeconds), cancellationToken)) .ConfigureAwait(false) == receivingTask) { if (receivingTask.Exception?.InnerException != null) { throw receivingTask.Exception.InnerException; } // Task completed within timeout. // Consider that the task may have faulted or been canceled. // We re-await the task so that any exceptions/cancellation is re-thrown. response = await receivingTask.ConfigureAwait(false); } else { // Timeout happen throw new TimeoutException(); } } finally { _twinResponseCompletions.TryRemove(correlationId, out _); if (Logging.IsEnabled) { Logging.Exit(this, cancellationToken, nameof(RoundTripTwinMessageAsync)); } } return(response); }
public async Task SendTwinMessageAsync(AmqpTwinMessageType amqpTwinMessageType, string correlationId, TwinCollection reportedProperties, TimeSpan timeout) { if (Logging.IsEnabled) { Logging.Enter(this, timeout, $"{nameof(SendTwinMessageAsync)}"); } await EnableTwinLinksAsync(timeout).ConfigureAwait(false); Debug.Assert(_twinSendingLink != null); try { AmqpIoTOutcome amqpIoTOutcome; switch (amqpTwinMessageType) { case AmqpTwinMessageType.Get: amqpIoTOutcome = await _twinSendingLink.SendTwinGetMessageAsync(correlationId, reportedProperties, timeout).ConfigureAwait(false); if (amqpIoTOutcome != null) { amqpIoTOutcome.ThrowIfNotAccepted(); } break; case AmqpTwinMessageType.Patch: amqpIoTOutcome = await _twinSendingLink.SendTwinPatchMessageAsync(correlationId, reportedProperties, timeout).ConfigureAwait(false); if (amqpIoTOutcome != null) { amqpIoTOutcome.ThrowIfNotAccepted(); } break; case AmqpTwinMessageType.Put: amqpIoTOutcome = await _twinSendingLink.SubscribeToDesiredPropertiesAsync(correlationId, timeout).ConfigureAwait(false); if (amqpIoTOutcome != null) { amqpIoTOutcome.ThrowIfNotAccepted(); } break; default: break; } } finally { if (Logging.IsEnabled) { Logging.Exit(this, timeout, $"{nameof(SendTwinMessageAsync)}"); } } }
public async Task SendTwinMessageAsync( AmqpTwinMessageType amqpTwinMessageType, string correlationId, TwinCollection reportedProperties, CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, nameof(SendTwinMessageAsync)); } await EnableTwinLinksAsync(cancellationToken).ConfigureAwait(false); Debug.Assert(_twinSendingLink != null); try { AmqpIotOutcome amqpIotOutcome; switch (amqpTwinMessageType) { case AmqpTwinMessageType.Get: amqpIotOutcome = await _twinSendingLink.SendTwinGetMessageAsync(correlationId, cancellationToken).ConfigureAwait(false); amqpIotOutcome?.ThrowIfNotAccepted(); break; case AmqpTwinMessageType.Patch: amqpIotOutcome = await _twinSendingLink.SendTwinPatchMessageAsync(correlationId, reportedProperties, cancellationToken).ConfigureAwait(false); amqpIotOutcome?.ThrowIfNotAccepted(); break; case AmqpTwinMessageType.Put: amqpIotOutcome = await _twinSendingLink.SubscribeToDesiredPropertiesAsync(correlationId, cancellationToken).ConfigureAwait(false); amqpIotOutcome?.ThrowIfNotAccepted(); break; } } finally { if (Logging.IsEnabled) { Logging.Exit(this, nameof(SendTwinMessageAsync)); } } }
private async Task <Twin> RoundTripTwinMessage(AmqpTwinMessageType amqpTwinMessageType, TwinCollection reportedProperties, CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, cancellationToken, $"{nameof(RoundTripTwinMessage)}"); } string correlationId = Guid.NewGuid().ToString(); Twin response = null; try { var taskCompletionSource = new TaskCompletionSource <Twin>(); _twinResponseCompletions[correlationId] = taskCompletionSource; await _amqpUnit.SendTwinMessageAsync(amqpTwinMessageType, correlationId, reportedProperties, _operationTimeout).ConfigureAwait(false); var receivingTask = taskCompletionSource.Task; if (await Task.WhenAny(receivingTask, Task.Delay(TimeSpan.FromSeconds(ResponseTimeoutInSeconds))).ConfigureAwait(false) == receivingTask) { // Task completed within timeout. // Consider that the task may have faulted or been canceled. // We re-await the task so that any exceptions/cancellation is rethrown. response = await receivingTask.ConfigureAwait(false); if (response == null) { throw new InvalidOperationException("Service response is null"); } } else { // Timeout happen throw new TimeoutException(); } } finally { _twinResponseCompletions.TryRemove(correlationId, out _); if (Logging.IsEnabled) { Logging.Exit(this, cancellationToken, $"{nameof(RoundTripTwinMessage)}"); } } return(response); }