Kaveh Shahbazian
Kaveh Shahbazian

Reputation: 13523

Multiple Queues in MSMQ (Performance Drops)

Why performance of MSMQ drops (~one third) when I use 10 queues instead of 1 queue?

In short MSMQ performance drops magnificently when I use more than 1 queue in a multithreaded application (receiving from each queue in a different thread).

It is like that MSMQ classes in .NET has a shared resource that shrinks when number of queues increase. BTW I am using Windows 7 for these tests with Visual Studio 2010.

Note: I had 1 queue for communicating between 2 applications. I need to use just recoverable mode. It was working fine until it hit a 100-150 message/sec wall. Then I thought I can increase processing power by increasing number of queues to 10 and processing them in parallel. But when I did receiving time increased almost 3 times more! :O

I wrote my applications using C#. I initialize my reader threads this way:

for (int i = 101; i <= 110; i++)
{
    var t = new Task<Tuple<TimeSpan, int, int, int>>(SingleQueueReceiver, i, TaskCreationOptions.LongRunning);
    tasks.Add(t);
}
foreach (var t in tasks) t.Start();

And my queue names are buffer101 to buffer110 which I have already created them. They are not transactional. My receiver task function (thread) is this:

static Tuple<TimeSpan, int, int, int> SingleQueueReceiver(object o)
{
    var qID = (int)o;

    TimeSpan SingleQueueReceiver_Elapsed = TimeSpan.FromMilliseconds(0);
    int SingleQueueReceiver_Count = 0;
    var watch = new Stopwatch();
    watch.Start();

    using (var q = new MessageQueue(string.Format(@".\private$\buffer{0}", qID), QueueAccessMode.Receive))
    {
        q.UseJournalQueue = false;
        var @continue = true;
        var sleep = TimeSpan.FromMilliseconds(1);

        while (true)
        {
            if (!@continue)
            {
                watch.Stop();
                SingleQueueReceiver_Elapsed = watch.Elapsed.Subtract(sleep);

                return Tuple.Create(SingleQueueReceiver_Elapsed, SingleQueueReceiver_Count, qID, 2);
            }

            try
            {
                var m = q.Receive(sleep);

                SingleQueueReceiver_Count++;
            }
            catch (MessageQueueException mqe)
            {
                if (mqe.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout) @continue = false;
            }
        }
    }
}

Upvotes: 3

Views: 936

Answers (1)

tom redfern
tom redfern

Reputation: 31760

I think it's more likely that the drop in performance is due to context switching or other multithreading side-effect than having multiple msmq queues.

Have you tried scaling out to 10 queues and 10 single-threaded listeners?

If you post your code then we can see what's going on hopefully.

Upvotes: 2

Related Questions