public async Task ProcessMessages() { await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false)) { string connectionString = TestEnvironment.ServiceBusConnectionString; string queueName = scope.QueueName; await using var client = GetClient(); #region Snippet:ServiceBusProcessMessages //@@ string connectionString = "<connection_string>"; //@@ string queueName = "<queue_name>"; // since ServiceBusClient implements IAsyncDisposable we create it with "await using" //@@ await using var client = new ServiceBusClient(connectionString); // create the sender ServiceBusSender sender = client.CreateSender(queueName); // create a message batch that we can send ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync(); messageBatch.TryAddMessage(new ServiceBusMessage(Encoding.UTF8.GetBytes("First"))); messageBatch.TryAddMessage(new ServiceBusMessage(Encoding.UTF8.GetBytes("Second"))); // send the message batch await sender.SendMessagesAsync(messageBatch); // get the options to use for configuring the processor var options = new ServiceBusProcessorOptions { // By default after the message handler returns, the processor will complete the message // If I want more fine-grained control over settlement, I can set this to false. AutoComplete = false, // I can also allow for multi-threading MaxConcurrentCalls = 2 }; // create a processor that we can use to process the messages ServiceBusProcessor processor = client.CreateProcessor(queueName, options); // since the message handler will run in a background thread, in order to prevent // this sample from terminating immediately, we can use a task completion source that // we complete from within the message handler. TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); processor.ProcessMessageAsync += MessageHandler; processor.ProcessErrorAsync += ErrorHandler; async Task MessageHandler(ProcessMessageEventArgs args) { string body = args.Message.Body.ToString(); Console.WriteLine(body); // we can evaluate application logic and use that to determine how to settle the message. await args.CompleteMessageAsync(args.Message); tcs.SetResult(true); } Task ErrorHandler(ProcessErrorEventArgs args) { // the error source tells me at what point in the processing an error occurred Console.WriteLine(args.ErrorSource); // the fully qualified namespace is available Console.WriteLine(args.FullyQualifiedNamespace); // as well as the entity path Console.WriteLine(args.EntityPath); Console.WriteLine(args.Exception.ToString()); return(Task.CompletedTask); } await processor.StartProcessingAsync(); // await our task completion source task so that the message handler will be invoked at least once. await tcs.Task; // stop processing once the task completion source was completed. await processor.StopProcessingAsync(); #endregion } }
public async Task SendAndReceiveMessageSafeBatch() { await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: false)) { #if SNIPPET string connectionString = "<connection_string>"; string queueName = "<queue_name>"; #else string connectionString = TestEnvironment.ServiceBusConnectionString; string queueName = scope.QueueName; #endif // since ServiceBusClient implements IAsyncDisposable we create it with "await using" await using var client = new ServiceBusClient(connectionString); // create the sender ServiceBusSender sender = client.CreateSender(queueName); #region Snippet:ServiceBusSendAndReceiveSafeBatch // add the messages that we plan to send to a local queue Queue <ServiceBusMessage> messages = new Queue <ServiceBusMessage>(); messages.Enqueue(new ServiceBusMessage("First message")); messages.Enqueue(new ServiceBusMessage("Second message")); messages.Enqueue(new ServiceBusMessage("Third message")); // create a message batch that we can send // total number of messages to be sent to the Service Bus queue int messageCount = messages.Count; // while all messages are not sent to the Service Bus queue while (messages.Count > 0) { // start a new batch using ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync(); // add the first message to the batch if (messageBatch.TryAddMessage(messages.Peek())) { // dequeue the message from the .NET queue once the message is added to the batch messages.Dequeue(); } else { // if the first message can't fit, then it is too large for the batch throw new Exception($"Message {messageCount - messages.Count} is too large and cannot be sent."); } // add as many messages as possible to the current batch while (messages.Count > 0 && messageBatch.TryAddMessage(messages.Peek())) { // dequeue the message from the .NET queue as it has been added to the batch messages.Dequeue(); } // now, send the batch await sender.SendMessagesAsync(messageBatch); // if there are any remaining messages in the .NET queue, the while loop repeats } #endregion // create a receiver that we can use to receive the messages ServiceBusReceiver receiver = client.CreateReceiver(queueName); // the received message is a different type as it contains some service set properties IReadOnlyList <ServiceBusReceivedMessage> receivedMessages = await receiver.ReceiveMessagesAsync(maxMessages : 2); foreach (ServiceBusReceivedMessage receivedMessage in receivedMessages) { // get the message body as a string string body = receivedMessage.Body.ToString(); } } }
public async Task ProcessSessionMessages() { await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true)) { #region Snippet:ServiceBusProcessSessionMessages #if SNIPPET string connectionString = "<connection_string>"; string queueName = "<queue_name>"; // since ServiceBusClient implements IAsyncDisposable we create it with "await using" await using var client = new ServiceBusClient(connectionString); #else string connectionString = TestEnvironment.ServiceBusConnectionString; string queueName = scope.QueueName; await using var client = CreateClient(); #endif // create the sender ServiceBusSender sender = client.CreateSender(queueName); // create a message batch that we can send ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync(); messageBatch.TryAddMessage( new ServiceBusMessage("First") { SessionId = "Session1" }); messageBatch.TryAddMessage( new ServiceBusMessage("Second") { SessionId = "Session2" }); // send the message batch await sender.SendMessagesAsync(messageBatch); #region Snippet:ServiceBusConfigureSessionProcessor // create the options to use for configuring the processor var options = new ServiceBusSessionProcessorOptions { // By default after the message handler returns, the processor will complete the message // If I want more fine-grained control over settlement, I can set this to false. AutoCompleteMessages = false, // I can also allow for processing multiple sessions MaxConcurrentSessions = 5, // By default or when AutoCompleteMessages is set to true, the processor will complete the message after executing the message handler // Set AutoCompleteMessages to false to [settle messages](https://docs.microsoft.com/en-us/azure/service-bus-messaging/message-transfers-locks-settlement#peeklock) on your own. // In both cases, if the message handler throws an exception without settling the message, the processor will abandon the message. MaxConcurrentCallsPerSession = 2, // Processing can be optionally limited to a subset of session Ids. SessionIds = { "my-session", "your-session" }, }; // create a session processor that we can use to process the messages await using ServiceBusSessionProcessor processor = client.CreateSessionProcessor(queueName, options); // configure the message and error handler to use processor.ProcessMessageAsync += MessageHandler; processor.ProcessErrorAsync += ErrorHandler; async Task MessageHandler(ProcessSessionMessageEventArgs args) { var body = args.Message.Body.ToString(); // we can evaluate application logic and use that to determine how to settle the message. await args.CompleteMessageAsync(args.Message); // we can also set arbitrary session state using this receiver // the state is specific to the session, and not any particular message await args.SetSessionStateAsync(new BinaryData("some state")); } Task ErrorHandler(ProcessErrorEventArgs args) { // the error source tells me at what point in the processing an error occurred Console.WriteLine(args.ErrorSource); // the fully qualified namespace is available Console.WriteLine(args.FullyQualifiedNamespace); // as well as the entity path Console.WriteLine(args.EntityPath); Console.WriteLine(args.Exception.ToString()); return(Task.CompletedTask); } // start processing await processor.StartProcessingAsync(); // since the processing happens in the background, we add a Conole.ReadKey to allow the processing to continue until a key is pressed. Console.ReadKey(); #endregion #endregion } }
static async Task SendMessageBatchAsync() { // create a Service Bus client await using (ServiceBusClient client = new ServiceBusClient(connectionString)) { // create a sender for the queue ServiceBusSender sender = client.CreateSender(queueName); // get the messages to be sent to the Service Bus queue Queue<ServiceBusMessage> messages = CreateMessages(); // total number of messages to be sent to the Service Bus queue int messageCount = messages.Count; // while all messages are not sent to the Service Bus queue while (messages.Count > 0) { // start a new batch using ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync(); // add the first message to the batch if (messageBatch.TryAddMessage(messages.Peek())) { // dequeue the message from the .NET queue once the message is added to the batch messages.Dequeue(); } else { // if the first message can't fit, then it is too large for the batch throw new Exception($"Message {messageCount - messages.Count} is too large and cannot be sent."); } // add as many messages as possible to the current batch while (messages.Count > 0 && messageBatch.TryAddMessage(messages.Peek())) { // dequeue the message from the .NET queue as it has been added to the batch messages.Dequeue(); } // now, send the batch await sender.SendMessagesAsync(messageBatch); // if there are any remaining messages in the .NET queue, the while loop repeats } Console.WriteLine($"Sent a batch of {messageCount} messages to the topic: {queueName}"); } }