async Task DisposeMessagesAsync(IEnumerable <Guid> lockTokens, Outcome outcome) { TimeoutHelper timeoutHelper = new TimeoutHelper(this.OperationTimeout, true); IList <ArraySegment <byte> > deliveryTags = this.ConvertLockTokensToDeliveryTags(lockTokens); ReceivingAmqpLink receiveLink = await this.ReceiveLinkManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); Task <Outcome>[] disposeMessageTasks = new Task <Outcome> [deliveryTags.Count]; int i = 0; foreach (ArraySegment <byte> deliveryTag in deliveryTags) { disposeMessageTasks[i++] = Task.Factory.FromAsync( (c, s) => receiveLink.BeginDisposeMessage(deliveryTag, outcome, true, timeoutHelper.RemainingTime(), c, s), a => receiveLink.EndDisposeMessage(a), this); } await Task.WhenAll(disposeMessageTasks).ConfigureAwait(false); }
/// <summary> /// Completes a series of <see cref="ServiceBusMessage"/> using a list of lock tokens. This will delete the message from the service. /// </summary> /// /// <param name="lockTokens">An <see cref="IEnumerable{T}"/> containing the lock tokens of the corresponding messages to complete.</param> /// <param name="outcome"></param> /// <param name="timeout"></param> internal override async Task DisposeMessagesAsync( IEnumerable <Guid> lockTokens, Outcome outcome, TimeSpan timeout) { if (_isSessionReceiver) { // TODO - ThrowIfSessionLockLost(); } List <ArraySegment <byte> > deliveryTags = ConvertLockTokensToDeliveryTags(lockTokens); ReceivingAmqpLink receiveLink = null; try { ArraySegment <byte> transactionId = AmqpConstants.NullBinary; //var ambientTransaction = Transaction.Current; //if (ambientTransaction != null) //{ // transactionId = await AmqpTransactionManager.Instance.EnlistAsync(ambientTransaction, ServiceBusConnection).ConfigureAwait(false); //} if (!ReceiveLink.TryGetOpenedObject(out receiveLink)) { receiveLink = await ReceiveLink.GetOrCreateAsync(timeout).ConfigureAwait(false); } var disposeMessageTasks = new Task <Outcome> [deliveryTags.Count]; var i = 0; foreach (ArraySegment <byte> deliveryTag in deliveryTags) { disposeMessageTasks[i++] = Task.Factory.FromAsync( (c, s) => receiveLink.BeginDisposeMessage(deliveryTag, transactionId, outcome, true, timeout, c, s), a => receiveLink.EndDisposeMessage(a), this); } var outcomes = await Task.WhenAll(disposeMessageTasks).ConfigureAwait(false); Error error = null; foreach (Outcome item in outcomes) { var disposedOutcome = item.DescriptorCode == Rejected.Code && ((error = ((Rejected)item).Error) != null) ? item : null; if (disposedOutcome != null) { if (error.Condition.Equals(AmqpErrorCode.NotFound)) { if (_isSessionReceiver) { // throw new SessionLockLostException(Resources.SessionLockExpiredOnMessageSession); } // throw new MessageLockLostException(Resources.MessageLockLost); } // throw error.ToMessagingContractException(); } } } catch (Exception exception) { if (exception is OperationCanceledException && receiveLink != null && receiveLink.State != AmqpObjectState.Opened) { // The link state is lost, We need to return a non-retriable error. // MessagingEventSource.Log.LinkStateLost(ClientId, receiveLink.Name, receiveLink.State, isSessionReceiver, exception); if (_isSessionReceiver) { // throw new SessionLockLostException(Resources.SessionLockExpiredOnMessageSession); } // throw new MessageLockLostException(Resources.MessageLockLost); } // throw AmqpExceptionHelper.GetClientException(exception); throw; } }
async Task DisposeMessagesAsync(IEnumerable <Guid> lockTokens, Outcome outcome) { TimeoutHelper timeoutHelper = new TimeoutHelper(this.OperationTimeout, true); IList <ArraySegment <byte> > deliveryTags = this.ConvertLockTokensToDeliveryTags(lockTokens); ReceivingAmqpLink receiveLink = null; try { receiveLink = await this.ReceiveLinkManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); Task <Outcome>[] disposeMessageTasks = new Task <Outcome> [deliveryTags.Count]; int i = 0; foreach (ArraySegment <byte> deliveryTag in deliveryTags) { disposeMessageTasks[i++] = Task.Factory.FromAsync( (c, s) => receiveLink.BeginDisposeMessage(deliveryTag, outcome, true, timeoutHelper.RemainingTime(), c, s), a => receiveLink.EndDisposeMessage(a), this); } Outcome[] outcomes = await Task.WhenAll(disposeMessageTasks).ConfigureAwait(false); Error error = null; foreach (Outcome item in outcomes) { var disposedOutcome = item.DescriptorCode == Rejected.Code && ((error = ((Rejected)item).Error) != null) ? item : null; if (disposedOutcome != null) { if (error.Condition.Equals(AmqpErrorCode.NotFound)) { if (this.isSessionReceiver) { throw new SessionLockLostException(Resources.SessionLockExpiredOnMessageSession); } else { throw new MessageLockLostException(Resources.MessageLockLost); } } throw AmqpExceptionHelper.ToMessagingContractException(error); } } } catch (Exception exception) { if (exception is OperationCanceledException && receiveLink != null && receiveLink.State != AmqpObjectState.Opened) { if (this.isSessionReceiver) { throw new SessionLockLostException(Resources.SessionLockExpiredOnMessageSession); } else { throw new MessageLockLostException(Resources.MessageLockLost); } } throw AmqpExceptionHelper.GetClientException(exception); } }