在 C# 中使用 MSMQ 验证异常队列

Validation Exception Queue using MSMQ in C#

我是Windows服务器中Microsoft Message Queue的新手,如果EmployeeID为NULL,我需要推送。

员工模型Class是

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
    }
}

一旦数据被推入验证异常队列,它应该由单独的进程处理。该过程每 1 小时需要启动一次,它应该调用以下方法

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

    // Log the Error
}

请指导我如何创建和处理它。

第一步: 在 server/pc

上将 MSMQ 作为 windows 功能安装

然后:
- 如果队列不存在则创建队列
- 异步推送队列中的消息
有用guide

从 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");

        }
    }


另一种广泛使用的方法是使用开箱即用的记录器,它已经包含此功能,例如 Enterprise Library 或 NLog,它们提供了简单的接口来做到这一点。

对于检索消息,我会推荐一个单独的 windows 服务,它会定期读取消息并处理它们。这里给出了一个关于如何做到这一点的很好的例子:Windows service with timer

更新: Windows 服务示例:

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();
    }

}

和MessageProcessor.cs

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