This article is contributed. See the original author and article here.

Test Entities: 


I use a same Queue to do this test. The Max delivery count is 1 If you are interested about the usage of “Max delivery count” please check from here Service Bus exceeding MaxDeliveryCount 


Message lock duration time is 30s.  


Scarlett_liu_0-1611052688610.jpeg


My Program: 


Here I use different function in .Net for receive messages. All the functions have Async” like ReceiveBatchAsync means the functions are working Asynchronously. 


 


To simulate the situation by sending a large number of messages, I received 5000 messages at one operation. 


 



  • Here is the program that complete messages in Asynchronous patterns.  


using Microsoft.ServiceBus.Messaging; 


using System; 


using System.Collections.Generic; 


using System.Linq; 


using System.Text; 


using System.Threading.Tasks; 


 


namespace SendReceiveQueue 


{ 


    class Program 


    { 


        static string connectionString = <your connection string>; 


        static string queueName = <queue name>; 


        static void Main(string[args) 


        { 


            MainAsync().GetAwaiter().GetResult(); 


        } 


        public static async Task MainAsync() 


        { 


            QueueClient receiveClient = QueueClient.CreateFromConnectionString(connectionStringqueueName); 


            //create a sender on the queue 


            var Timestamp2 = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds(); 


            Console.WriteLine(“Receiving message -, timestamp:{0}”, Timestamp2); 


 


 


             IEnumerable<BrokeredMessagemessageList = await receiveClient.ReceiveBatchAsync(5000); 


            foreach (BrokeredMessage message in messageList) 


            { 


                try 


                { 


                    var Timestamp0 = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds(); 


                    Console.WriteLine(“Message”+message.GetBody<string>() +“time”+Timestamp0); 


 


                    message.CompleteAsync(); 


                } 


                catch (Exception ex) 


                { 


                    var Timestamp3 = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds(); 


                    Console.WriteLine(“abandon message – timestamp:{0},errorr message {1}”, Timestamp3,ex.Message); 


                    await message.AbandonAsync(); 


                } 


            } 


 


            await receiveClient.CloseAsync(); 


        } 


    } 


} 


 


This is the result. The average time of receiving message is in 200ms to 300ms. 


Scarlett_liu_1-1611052688631.jpeg



  • And this is the Code for receiving messages with Synchronous messaging patterns.  


using Microsoft.ServiceBus.Messaging; 


using System; 


using System.Collections.Generic; 


using System.Linq; 


using System.Text; 


 


 


namespace SendReceiveQueue 


{ 


    class Program 


    { 


        static string connectionString = <your connection string>; 


        static string queueName = <queue name>; 


        static void Main(string[args) 


        { 


            MainTest(); 


        } 


        static void MainTest() 


        { 


            QueueClient receiveClient = QueueClient.CreateFromConnectionString(connectionStringqueueName); 


            //create a sender on the queue 


            var Timestamp2 = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds(); 


            Console.WriteLine(“Receiving message -, timestamp:{0}”, Timestamp2); 


 


            IEnumerable<BrokeredMessagemessageList = receiveClient.ReceiveBatch(5000); 


            foreach (BrokeredMessage message in messageList) 


            { 


                try 


                { 


                    var Timestamp0 = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds(); 


                    Console.WriteLine(“Message” + message.GetBody<string>() + “time” + Timestamp0); 


 


                    message.Complete(); 


                } 


                catch (Exception ex) 


                { 


                    var Timestamp3 = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds(); 


                    Console.WriteLine(“abandon message – timestamp:{0},errorr message {1}”, Timestamp3, ex.Message); 


                    message.Abandon(); 


                } 


            } 


 


            receiveClient.Close(); 


            Console.Read(); 


        } 


    } 


} 


 


This is the result. At first time the messages can also finish in 200ms to 300ms. But after a while It shows error for “lock expired”.  


Scarlett_liu_2-1611052688638.jpeg


Why didn’t we get any errors while using the Async pattern in this program? Why we got “Lock expired” exception while using Sync pattern 


This exception is highly possible in receiving messages in one operation. Using Peeklock receive mode, Service Bus locked all the 5000 messages at the same time. And then complete messages in Asynchronous pattern, Messages can be completed without blocking 


But using Synchronous pattern, all the Messages was completed one by one, the waiting time exceeds 30s. So, it shows “lock expired” error.  


You can get detailed information on how the asynchronous C# backend works from this document. Asynchronous programming in C# | Microsoft Docs 


 


Test Result Summary 



  • From the test result, it indicates that Asynchronous Messaging pattern is more efficient since it will return immediatelyWe recommend using Asynchronous over than Synchronous. 

  • As mentioned before this “Lock expired” exception may be due to many reasons. That also the reason Service Bus have Dead Lettering Queue to prevent Service Bus message being lost. If you are interested in this topic, you are welcome to provide your comments.  

Brought to you by Dr. Ware, Microsoft Office 365 Silver Partner, Charleston SC.