Search code examples
c#.netmessage-queuemsmqtask-queue

Validation Exception Queue using MSMQ in C#


I'm new in Microsoft Message Queue in Windows Server, I need to push, if the EmployeeID is NULL.

The Employee Model Class is

public class Employee
{
    public string EmployeeID { get; set; }
    public string EmployeeName { get; set; }
}

public void ValidationProcess(Employee emp)
{
    if((emp != null) || (emp.EmployeeID == null))
    {
       // Push into Validation Exception Queue using MSMQ
    }
}

Once the Data pushed into that Validation Exception Queue, it should be processed by separate process. Every 1hr the process need to initiate and it should call the following method

public void ValidationExceptionProcess(object obj)
{
    // Some Inner Process

    // Log the Error
}

Kindly guide me how to create and process it.


Solution

  • First Step: Install MSMQs as a windows feature on the server/pc

    Then:
    - Create the queue if it does not exist
    - Push the message in the queue asynchronously
    Useful guide

    Code example for pushing and retrieving messages from msmq:

    public class ExceptionMSMQ
        {
            private static readonly string description = "Example description";
            private static readonly string path = @".\Private$\myqueue";
            private static MessageQueue exceptionQueue;
            public static MessageQueue ExceptionQueue
            {
                get
                {
                    if (exceptionQueue == null)
                    {
                        try
                        {
                            if (MessageQueue.Exists(path))
                            {
                                exceptionQueue = new MessageQueue(path);
                                exceptionQueue.Label = description;
                            }
                            else
                            {
                                MessageQueue.Create(path);
                                exceptionQueue = new MessageQueue(path);
                                exceptionQueue.Label = description;
                            }
                        }
                        catch
                        {
                            throw;
                        }
                        finally
                        {
                            exceptionQueue.Dispose();
                        }
                    }
                    return exceptionQueue;
                }
            }
    
            public static void PushMessage(string message)
            {
                ExceptionQueue.Send(message);
            }
    
            private static List<string> RetrieveMessages()
            {
                List<string> messages = new List<string>();
                using (ExceptionQueue)
                {
                    System.Messaging.Message[] queueMessages = ExceptionQueue.GetAllMessages();
                    foreach (System.Messaging.Message message in queueMessages)
                    {
                        message.Formatter = new XmlMessageFormatter(
                        new String[] { "System.String, mscorlib" });
                        string msg = message.Body.ToString();
                        messages.Add(msg);
                    }
                }
                return messages;
            }
    
            public static void Main(string[] args)
            {
                ExceptionMSMQ.PushMessage("my exception string");
    
            }
        }
    


    An other widely used way to do that would also be to use out of the box loggers which already contains this functionality like Enterprise Library or NLog which provide easy interfaces to do that.

    For retrieving messages I would recommend a separate windows service which would periodically read messages and process them. An good example on how to do that is given here: Windows service with timer

    Update: Windows Service Example:

    MSMQConsumerService.cs

    public partial class MSMQConsumerService : ServiceBase
    {
        private System.Timers.Timer timer;
    
        public MSMQConsumerService()
        {
            InitializeComponent();
        }
    
        protected override void OnStart(string[] args)
        {
            this.timer = new System.Timers.Timer(30000D);  // 30000 milliseconds = 30 seconds
            this.timer.AutoReset = true;
            this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.ProcessQueueMessages);
            this.timer.Start();
        }
    
        protected override void OnStop()
        {
            this.timer.Stop();
            this.timer = null;
        }
    
        private void ProcessQueueMessages(object sender, System.Timers.ElapsedEventArgs e)
        {
            MessageProcessor.StartProcessing();
        }
    
    }
    

    and the MessageProcessor.cs

    public class MessageProcessor
        {
            public static void StartProcessing()
            {
                List<string> messages = ExceptionMSMQ.RetrieveMessages();
                foreach(string message in messages)
                {
                    //write message in database
                }
            }
        }