public Task <TResponse> RequestAsync( TRequest request, CancellationToken ct, Priority priority = Priority.Normal, Action <IRequestEnhancer> requestEnhancer = null) { if (_disposed) { throw new ObjectDisposedException(GetType().Name); } return(_retryPolicy.ExecuteAsync(async() => { try { var requestId = Guid.NewGuid().ToString(); var requestData = Serializer.Serialize(request); var publisherIndex = GetNextPublisherIndex(PublishingPoolSize); var publisherModel = _publisherModels[publisherIndex]; var publisherLock = _publisherLocks[publisherIndex]; var consumerIndex = GetNextConsumerIndex(ConsumingPoolSize); var consumer = _consumers[consumerIndex]; lock (publisherLock) { var props = publisherModel.CreateBasicProperties(); props.Persistent = false; props.CorrelationId = requestId; props.ReplyTo = consumer.QueueName; props.Priority = priority.GetValue(); requestEnhancer?.Invoke(new RequestEnhancer(props)); consumer.AddRequest(requestId); publisherModel.BasicPublish(ExchangeName, OperationName, props, requestData); } var responseData = await consumer.GetResponse(requestId, MaximumTimeout, ct); var response = Serializer.Deserialize <TResponse>(responseData); return response; } catch (Exception ex) { Logger.Log(LogLevel.Error, "An unhandled exception occured.", ex); throw; } })); }