Search code examples
c#msmq

How should I use MSMQ?


I wrote this code which is working but it made me start thinking how should I use MSMQ: Should I use a "using" statement to get the message queue? the Using statement will handle getting rid of the queue when I am done with it, but when am I done with it? Should I save my MessageQueue object for reuse. Lets say this is in an ASP.Net application and I want to send 3 messages to the same queue from the same action. Save the object and reuse or create and dispose as I am right now?

using (MessageQueue msgQueue = new MessageQueue(this.queueName))
{
    using (MessageQueueTransaction msgTx = new MessageQueueTransaction())
    {                      
        Message recoverableMessage = null;
        msgTx.Begin();
        try
        {
            recoverableMessage = new Message();
            recoverableMessage.Body = message;
            recoverableMessage.Formatter = new BinaryMessageFormatter(System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple, System.Runtime.Serialization.Formatters.FormatterTypeStyle.TypesAlways);
            recoverableMessage.Recoverable = true;

            msgQueue.Send(recoverableMessage, msgTx);
            ////this.msgQ.Send(recoverableMessage, msgTx); //whats up here??? this will teach me for taking time off. not sure whuc I shuold use
            msgTx.Commit();
            result = recoverableMessage.Id;
            //recoverableMessage.Dispose();
        }
        catch (Exception)
        {
            msgTx.Abort();
            ////recoverableMessage.Dispose();
        }
        finally
        {
            if (recoverableMessage != null)
            {
                recoverableMessage.Dispose();
            }
        }
    }
}

Solution

  • In general, you should keep objects alive as short as possible. This is to prevent .NET garbage collector from moving those objects from generation 0 to generation 1 and so on. This will help to reduce memory consumption & number of garbage collections.

    Having said that, the only reason to keep a message queue object alive would be to post multiple messages to the same queue as part of a single transaction or scope.

    If the three messages are sent during a single page request, then you create a new instance of the message queue, send the messages and dispose of the queue each time a page is rendered.

    EDIT
    For details on thread satefy etc. you should refer to the documentation.
    For example, MSDN says that only the GetAllMessages method is thread safe. I would then assume that the rest of the API isn't thread safe. However, this only means that a single instance of MessageQueue object should not be accessed concurrently by multiple threads. You can create multiple instances of MessageQueue pointing to the same queue fine.

    Regarding performance, I think you may be trying to optimise prematurely. I suggest profiling your software (only the release build) and putting it under some load. That's the only way you'll get a reliable answer.