Using Message Queues In C#

Introduction

In today’s article we will look at message queues in C#. We will see what message queues are, why they are important, how to enable standard message queues in Windows 10, and how to create a simple message queue application in C#

What are Message Queues

These days we see many business scenarios where large amounts of data must be processed. If we do this in a synchronous or online manner, the whole process will be awfully slow and the application sending the data for processing would have to wait for the response to be received. Similarly, the application processing the data would be overloaded if many requests came in at the same time for processing. The solution to this problem is to use a mechanism that allows for requests to be stored or queued and then the processing or receiving application can pick up these requests one by one and process them. This process is called message queueing. What we do is send a message to the queue which keeps it until it is read by the same or another application. This gives us an offline experience where we can queue as many messages as we like and then these can be processed as required. The two applications, one loading the queue and the other one processing the queue could be on separate machines or processes.

Enabling MSMQ to implement messaging on Windows 10

The Microsoft implementation of Message Queues is MSMQ (Microsoft Message Queuing). We will now see how to turn on this feature on a Windows 10 machine. In order to use the Message Queuing mechanism, it must be turned on first. We can then create queues and use them in our application.

Open Control Panel

Open Control Panel

Next, select Programs

Select Programs

Next, select “Turn Windows features on or off”. You would need administrator privileges for this.

Turn Windows features on or off

Select, the Microsoft Message Queue server and click “ok”

Microsoft Message Queue

Once the feature is installed, you will see the above screen.

Next, we confirm if MSMQ was installed. Open “Computer Management” as below,

Computer Management

Let us create a private queue called “empSalary” as below. Right-click on Private Queues and select to create a new Queue,

EmpSalary

The private queue is now created.

In the next section, we will use this queue in a simple C# Windows application.

Simple Application to use Message Queues

We have now installed MSMQ and created a private queue. Let us now create a Windows Forms application using Visual Studio 2019 community edition. We will create a simple application to write and read from this queue.

MSMQ

New project

Configure new project

We now add the “System. Messaging” to the references below,

System Messaging

Add the code below,

Add code

Form1.cs

using System;
using System.Messaging;
using System.Windows.Forms;

namespace MsmqTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Code for form load event
        }

        private void btnLoadQueue_Click(object sender, EventArgs e)
        {
            var emp = new Employee()
            {
                Id = 100,
                Name = "John Doe",
                Hours = 55,
                Rate = 21.0
            };

            System.Messaging.Message msg = new System.Messaging.Message();
            msg.Body = emp;

            MessageQueue msgQ = new MessageQueue(".\\Private$\\empSalary");
            msgQ.Send(msg);
        }

        private void btnReadQueue_Click(object sender, EventArgs e)
        {
            MessageQueue msgQ = new MessageQueue(".\\Private$\\empSalary");
            var emp = new Employee();
            Object o = new Object();
            System.Type[] arrTypes = new System.Type[2];
            arrTypes[0] = emp.GetType();
            arrTypes[1] = o.GetType();

            msgQ.Formatter = new XmlMessageFormatter(arrTypes);
            emp = (Employee)msgQ.Receive().Body;

            lblDetails.Text = $"Employee name: {emp.Name}, Salary: {emp.Hours * emp.Rate}";
        }
    }

    public class Employee
    {
        public int Id;
        public string Name;
        public int Hours;
        public double Rate;
    }
}

Form1.Designer. cs

namespace MsmqTest
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        private void InitializeComponent()
        {
            this.btnLoadQueue = new System.Windows.Forms.Button();
            this.btnReadQueue = new System.Windows.Forms.Button();
            this.lblDetails = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // btnLoadQueue
            // 
            this.btnLoadQueue.Location = new System.Drawing.Point(135, 61);
            this.btnLoadQueue.Name = "btnLoadQueue";
            this.btnLoadQueue.Size = new System.Drawing.Size(240, 33);
            this.btnLoadQueue.TabIndex = 0;
            this.btnLoadQueue.Text = "Load Queue";
            this.btnLoadQueue.UseVisualStyleBackColor = true;
            this.btnLoadQueue.Click += new System.EventHandler(this.btnLoadQueue_Click);
            // 
            // btnReadQueue
            // 
            this.btnReadQueue.Location = new System.Drawing.Point(135, 159);
            this.btnReadQueue.Name = "btnReadQueue";
            this.btnReadQueue.Size = new System.Drawing.Size(240, 31);
            this.btnReadQueue.TabIndex = 1;
            this.btnReadQueue.Text = "Read Queue";
            this.btnReadQueue.UseVisualStyleBackColor = true;
            this.btnReadQueue.Click += new System.EventHandler(this.btnReadQueue_Click);
            // 
            // lblDetails
            // 
            this.lblDetails.AutoSize = true;
            this.lblDetails.Location = new System.Drawing.Point(135, 256);
            this.lblDetails.Name = "lblDetails";
            this.lblDetails.Size = new System.Drawing.Size(0, 13);
            this.lblDetails.TabIndex = 2;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(800, 450);
            this.Controls.Add(this.lblDetails);
            this.Controls.Add(this.btnReadQueue);
            this.Controls.Add(this.btnLoadQueue);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        #endregion

        private System.Windows.Forms.Button btnLoadQueue;
        private System.Windows.Forms.Button btnReadQueue;
        private System.Windows.Forms.Label lblDetails;
    }
}

This is a simple application in which, on the “Load Queue” button we create an employee class object and write it to the “empSalary” queue. Then, when we click the “Read Queue” button, we read the object and display the calculated salary in a label. In a real-life application, the two functions to load the queue and read from the queue would probably be in separate applications. However, for simplicity purposes I have created both functions in the same application.

When, we click “Load Queue”, an instance of the employee class is created and put onto the queue. We can see this below,

Load Queue

Once, we click the “Read Queue” button, this object or message is read from the queue and processed and is no longer visible in the queue as below,

Read Queue

Also, we see the result on the screen,

Result

Summary

In this article, we looked at Message Queues, what they are, and why they are important. Next, we saw how to enable the Message Queues server on Windows 10. A similar process will be used for enabling it on other Microsoft operating systems. We then created a private message queue and finally created a simple Windows Forms application in C# to first write a message to this queue and then read the message from the queue. The example was simple with both the loading and reading being done from the same screen. However, in a real-life scenario, the two functions can be done from separate applications residing on different servers and running in different processes. Hence, this is not only a way to process data in an offline mode but also connect applications across boundaries.

Happy Coding!


Similar Articles