MSMQ from .NET

It is often a requirement to reliably deliver messages even when the network is periodically down or the machine is power cycled. When using Windows, Microsoft Message Queuing (MSMQ) is an old standby for persistent storage of queued messages. This post looks at how to set up MSMQ and interact with it from .NET.

Code Please

A quick start project is available on Github if you would like to go straight to the code.

Installation and GUI Access

MSMQ is an optional Windows component that is not installed by default. Check your Windows Features list (GUI or command line). Check the box for Microsoft Message Queue (MSMQ) Server. Just check the top level which includes Core. We will not be using the other features in this post.

Once installed you can administer queues from Computer Management (compmgmt.msc). Find Message Queuing under the Services and Applications node. We will programatically create our queues in this post but you can manually interact with them here.


You will need to add a reference (within Assemblies) to System.Messaging from your project and add a using System.Messaging statement.

The System.Messaging.MessageQueue class is where the action is. Let’s step through it.

Queue Paths

There are a lot of ways to format the path to a queue. The most common case on an embedded system is a private queue on the local machine, which is addressed with:


You can also specify a remote machine name. For TCP and HTTP connections:


Note the slashes are in a different direction for TCP vs HTTP. More details here.


You need to decide at the time of queue creation whether or not the queue will be transactional. If you are performing an operation that may fail (network call), use a transactional queue. Reading from the queue will not permanently remove the entry until you separately call Commit. Calling Abort or disposing the transaction puts the record back in the queue.

Consider the possible failure mode of a message getting stuck in a queue. For example, the network is up but the message is improperly formatted and will never be accepted by the server. There may be valid messages stuck behind it. There are a number of strategies for addressing this situation which are well covered here.

Creating and Opening a Queue

Finally, some code! Here I create the queue if it does not exist or attach to an existing queue. Note I specify this queue is transactional in the constructor:

const string path = @".\private$\test";
MessageQueue queue = null;
if (!MessageQueue.Exists(path))
    queue = MessageQueue.Create(path, transactional: true);
    queue = new MessageQueue(path);


XML and Binary serialization of messages is provided out of the box. If you are able to declare all message types up front, you can set this up once with:

queue.Formatter = new XmlMessageFormatter(
    new Type[] { typeof(string) }

I’m just sending strings for example purposes but user defined types are also supported. Strictly speaking, the XmlMessageFormatter is already constructed as a default on the MessageQueue class. You could just set the target types directly but I find this ugly:

((XmlMessageFormatter)queue.Formatter).TargetTypes = new Type[] { typeof(string) };

Another technicality – you can delay specifying a formatter until you are actually sending (see Message constructor) or receiving (see Message.Formatter) a single message. You can dynamically mix message types in the same queue. I wouldn’t suggest that in most cases.

Sending a Message (non-transactionally)

Pretty simple, but with a subtle problem to point out. Note below how I wrap the string in a Message instance. The Send method takes an object, so you might think you can skip the wrapper. But don’t. Doing so will make your sending code not thread safe.

string input = Console.ReadLine();
queue.Send(new Message(input));

Reading Messages (non-transactionally)

Another deceptively simple bit of code:

Message message = queue.Receive();
string line = message.Body as string;

So what’s the catch? If there are no messages in the queue, the Receive method will block indefinitely. Typically, a queue reader is implemented on its own thread and is left always running. In that case blocking is just fine. My example project runs another thread for reading.

There is no explicit Count property on MessageQueue. The way MSMQ is normally used such a property is ephemeral. If you really need to read a queue until you reach empty, all options are moderately ugly. I do not vouch for any of these:

  • Set a timeout on the Receive method call, catch the MessageQueueException and make sure ex.MessageQueueErrorCode is MessageQueueErrorCode.IOTimeout. Yuk! And only feasible for local queues.
  • Use GetMessageEnumerator2. The ‘2’ inspires confidence.
  • Use MessagePropertyFilter.

Messages with Transactions

Home stretch. To have a separate Commit/Abort phase, create a MessageQueueTransaction and pass it to Send/Receive. Some gotchas:

  • Your queue must be created from birth with the transactional attribute set to true.
  • Be sure to call Begin on the transaction before you pass it or it will have no impact.
  • Even if your program logic does not require a transaction for sending, you will still need to pass the transaction object and commit it. Otherwise you will not get anything in the queue.
MessageQueueTransaction transaction = new MessageQueueTransaction();

    Message message = queue.Receive(transaction);

    // Do something that could fail (i.e. network call)

catch (Exception)


Some options for interacting with MSMQ on a running system:

Featured Image Credit

Second Childishness and Mere Oblivion. Photo by Nick Bushby.

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.