private async Task OpenMethodsReceiverLinkAsync(AmqpIotSession amqpIotSession, string correlationIdSuffix, CancellationToken cancellationToken) { if (_methodReceivingLink == null || _methodReceivingLink.IsClosing()) { _methodReceivingLink?.SafeClose(); _methodReceivingLink = await amqpIotSession .OpenMethodsReceiverLinkAsync(_deviceIdentity, correlationIdSuffix, cancellationToken) .ConfigureAwait(false); if (_methodReceiverLinkDisconnected == null) { _methodReceiverLinkDisconnected = (obj, arg) => { amqpIotSession.SafeClose(); }; } _methodReceivingLink.Closed += _methodReceiverLinkDisconnected; _methodReceivingLink.RegisterMethodListener(OnMethodReceived); if (Logging.IsEnabled) { Logging.Associate(this, _methodReceivingLink, nameof(_methodReceivingLink)); } } }
public async Task EnableEventReceiveAsync(CancellationToken cancellationToken) { if (_closed) { throw new IotHubException("Device is now offline.", false); } if (Logging.IsEnabled) { Logging.Enter(this, nameof(EnableEventReceiveAsync)); } AmqpIotSession amqpIotSession = await EnsureSessionIsOpenAsync(cancellationToken).ConfigureAwait(false); try { await _eventReceivingLinkSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { throw new TimeoutException("Failed to enter the semaphore required for ensuring that AMQP event receiver links are open."); } try { if (_eventReceivingLink == null || _eventReceivingLink.IsClosing()) { _eventReceivingLink?.SafeClose(); _eventReceivingLink = await amqpIotSession .OpenEventsReceiverLinkAsync(_deviceIdentity, cancellationToken) .ConfigureAwait(false); if (_eventReceiverLinkDisconnected == null) { _eventReceiverLinkDisconnected = (obj, arg) => { amqpIotSession.SafeClose(); }; } _messageReceivingLink.Closed += _eventReceiverLinkDisconnected; _eventReceivingLink.RegisterEventListener(OnEventsReceived); if (Logging.IsEnabled) { Logging.Associate(this, this, _eventReceivingLink, nameof(EnableEventReceiveAsync)); } } } finally { _eventReceivingLinkSemaphore.Release(); if (Logging.IsEnabled) { Logging.Exit(this, nameof(EnableEventReceiveAsync)); } } }
private async Task OpenTwinReceiverLinkAsync(AmqpIotSession amqpIotSession, string correlationIdSuffix, TimeSpan timeout) { if (_twinReceivingLink == null || _twinReceivingLink.IsClosing()) { _twinReceivingLink?.SafeClose(); _twinReceivingLink = await amqpIotSession .OpenTwinReceiverLinkAsync(_deviceIdentity, correlationIdSuffix, timeout) .ConfigureAwait(false); _twinReceivingLink.Closed += (obj, arg) => { amqpIotSession.SafeClose(); }; _twinReceivingLink.RegisterTwinListener(OnDesiredPropertyReceived); Logging.Associate(this, _twinReceivingLink, nameof(_twinReceivingLink)); } }
private async Task EnsureMessageReceivingLinkIsOpenAsync(TimeSpan timeout, bool enableCallback = false) { if (_closed) { throw new IotHubException("Device is now offline.", false); } Logging.Enter(this, timeout, nameof(EnsureMessageReceivingLinkIsOpenAsync)); AmqpIotSession amqpIotSession = await EnsureSessionIsOpenAsync(timeout).ConfigureAwait(false); bool enteredSemaphore = await _messageReceivingLinkSemaphore.WaitAsync(timeout).ConfigureAwait(false); if (!enteredSemaphore) { throw new TimeoutException("Failed to enter the semaphore required for ensuring that AMQP message receiver links are open."); } try { if (_messageReceivingLink == null || _messageReceivingLink.IsClosing()) { _messageReceivingLink?.SafeClose(); _messageReceivingLink = await amqpIotSession.OpenMessageReceiverLinkAsync(_deviceIdentity, timeout).ConfigureAwait(false); _messageReceivingLink.Closed += (obj, arg) => { amqpIotSession.SafeClose(); }; Logging.Associate(this, this, _messageReceivingLink, nameof(EnsureMessageReceivingLinkIsOpenAsync)); } if (enableCallback) { _messageReceivingLink.RegisterReceiveMessageListener(OnDeviceMessageReceived); } } finally { _messageReceivingLinkSemaphore.Release(); Logging.Exit(this, timeout, nameof(EnsureMessageReceivingLinkIsOpenAsync)); } }
public async Task DisableMethodsAsync(TimeSpan timeout) { Logging.Enter(this, timeout, nameof(DisableMethodsAsync)); Debug.Assert(_methodSendingLink != null); Debug.Assert(_methodReceivingLink != null); bool enteredSemaphore = await _methodLinkSemaphore.WaitAsync(timeout).ConfigureAwait(false); if (!enteredSemaphore) { throw new TimeoutException("Failed to enter the semaphore required for ensuring that AMQP method sender and receiver links are closed."); } try { ICollection <Task> tasks = new List <Task>(); if (_methodReceivingLink != null) { tasks.Add(_methodReceivingLink.CloseAsync(timeout)); } if (_methodSendingLink != null) { tasks.Add(_methodSendingLink.CloseAsync(timeout)); } if (tasks.Count > 0) { await Task.WhenAll(tasks).ConfigureAwait(false); _methodReceivingLink = null; _methodSendingLink = null; } } finally { Logging.Exit(this, timeout, nameof(DisableMethodsAsync)); _methodLinkSemaphore.Release(); } }
public async Task DisableMethodsAsync(CancellationToken cancellationToken) { if (Logging.IsEnabled) { Logging.Enter(this, nameof(DisableMethodsAsync)); } Debug.Assert(_methodSendingLink != null); Debug.Assert(_methodReceivingLink != null); try { await _methodLinkSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { throw new TimeoutException("Failed to enter the semaphore required for ensuring that AMQP method sender and receiver links are closed."); } // These event handlers are in place for network drop cases and will try to close the session that this // link belongs to, but that isn't necessary when the client is deliberately closing just the link. if (_methodReceiverLinkDisconnected != null) { _methodReceivingLink.Closed -= _methodReceiverLinkDisconnected; } if (_methodSenderLinkDisconnected != null) { _methodSendingLink.Closed -= _methodSenderLinkDisconnected; } try { ICollection <Task> tasks = new List <Task>(2); if (_methodReceivingLink != null) { tasks.Add(_methodReceivingLink.CloseAsync(cancellationToken)); } if (_methodSendingLink != null) { tasks.Add(_methodSendingLink.CloseAsync(cancellationToken)); } if (tasks.Count > 0) { await Task.WhenAll(tasks).ConfigureAwait(false); _methodReceivingLink = null; _methodSendingLink = null; } } finally { if (Logging.IsEnabled) { Logging.Exit(this, nameof(DisableMethodsAsync)); } _methodLinkSemaphore.Release(); } }