Hi,
I am trying to work with a simple example of ServiceBus to place received items on to an in-memory queue, and then read them off at a later time from any number of processing threads.
This pattern is mentioned in the official documentation to increase throughput through a service bus.
Anyway, here's the example:
private static string _serviceBusConnectionString = "XXX"; private static BlockingCollection<BrokeredMessage> _incomingMessages = new BlockingCollection<BrokeredMessage>(); private static CancellationTokenSource _cancelToken = new CancellationTokenSource(); private static QueueClient _client; static void Main(string[] args) { // Set up a few listeners on different threads Task.Run(async () => { while (!_cancelToken.IsCancellationRequested) { var msg = _incomingMessages.Take(_cancelToken.Token); if (msg != null) { try { await msg.CompleteAsync(); Console.WriteLine($"Completed Message Id: {msg.MessageId}"); } catch (ObjectDisposedException) { Console.WriteLine("Message was disposed!?"); } } } }); // Now set up our service bus reader _client = GetQueueClient("test"); _client.OnMessageAsync(async (message) => { await Task.Run(() => _incomingMessages.Add(message)); }, new OnMessageOptions() { AutoComplete = false }); // Now start sending Task.Run(async () => { int sent = 0; while (!_cancelToken.IsCancellationRequested) { var msg = new BrokeredMessage(); await _client.SendAsync(msg); Console.WriteLine($"Sent {++sent}"); await Task.Delay(1000); } }); Console.ReadKey(); _cancelToken.Cancel(); } private static QueueClient GetQueueClient(string queueName) { var namespaceManager = NamespaceManager.CreateFromConnectionString(_serviceBusConnectionString); if (!namespaceManager.QueueExists(queueName)) { var settings = new QueueDescription(queueName); settings.MaxDeliveryCount = 10; settings.LockDuration = TimeSpan.FromSeconds(5); settings.EnableExpress = true; settings.EnablePartitioning = true; namespaceManager.CreateQueue(settings); } var factory = MessagingFactory.CreateFromConnectionString(_serviceBusConnectionString); factory.RetryPolicy = new RetryExponential(minBackoff: TimeSpan.FromSeconds(0.1), maxBackoff: TimeSpan.FromSeconds(30), maxRetryCount: 100); var queueClient = factory.CreateQueueClient(queueName); return queueClient; }
Playing around with settings I cannot get the BrokeredMessage to not be Disposed. As you can see, I'm not calling anything apart from the attempted call to .CompleteAsync.