C#隊列學習筆記:MSMQ入門一


    一、引言

    MSMQ全稱MicroSoft Message Queue,微軟消息隊列,是在多個不同的應用之間實現相互通信的一種異步傳輸模式,相互通信的應用可以分布於同一台機器上,也可以分布於相連的網絡空間中的任一位置。它的實現原理是:消息的發送者把自己想要發送的信息放入一個容器中(我們稱之為Message),然后把它保存至一個系統公用空間的消息隊列(Message Queue)中,本地或者異地的消息接收程序再從該隊列中取出發給它的消息進行處理。

    消息Message是由通信的雙方所需要傳遞的信息。消息是MSMQ的存儲對象,封裝為System.Messaging.Message對象,它由一個主體(body)和若干屬性構成,其中我們的用戶數據通常被序列化裝入body主體中,這也是我們稱它為數據容器的原因。除了body屬性,還有幾個屬性相對來說比較重要:Priority(消息的優先級),Label(用戶定義的消息標識),Formatter(消息的序列組件,當用戶將復雜類型數據填充到body中,用戶的數據會先被序列化)。

    隊列分事務性隊列和非事務性隊列,默認創建的是非事務性隊列。當我們勾選事務性復選框,就會創建事務性隊列。那么什么是事務性隊列呢?事務性隊列將消息保存在磁盤上,實現了持久化,也就是說當關機斷電后,下次再啟動機器,我們的消息依然保存在隊列里面,而非事務性隊列則將消息保存在內存中,也就是說重啟電腦后,隊列里面的消息將不存在了。

    隊列的類型主要包括以下幾種:

    “公共隊列”在整個“消息隊列”網絡中復制,並且有可能由網絡連接的所有站點訪問。

    “專用隊列”不在整個網絡中發布,相反,它們僅在所駐留的本地計算機上可用。專用隊列只能由知道隊列的完整路徑名或標簽的應用程序訪問。

    “管理隊列”包含確認在給定“消息隊列”網絡中發送的消息回執的消息。指定希望 MessageQueue 組件使用的管理隊列(如果有的話)。

    “響應隊列”包含目標應用程序接收到消息時返回給發送應用程序的響應消息。指定希望 MessageQueue 組件使用的響應隊列(如果有的話)。

    優點:穩定、消息優先級、脫機能力以及安全性,有保障的消息傳遞和執行許多業務處理的可靠的防故障機制。

    缺點:MSMQ不適合於Client需要Server端實時交互情況;大量請求的時候響應延遲。

    二、安裝

    在運行中輸入appwiz.cpl->打開或關閉 Windows 功能->Microsoft Message Queue (MSMQ) 服務器。

 

    安裝成功后,在運行中輸入compmgmt.msc->服務和應用程序->消息隊列。

    右鍵消息隊列->屬性,可更改默認存儲路徑等。

    三、示例演示

    注意:需引用System.Messaging。

    class Program
    {
        static void Main(string[] args)
        {
            #region MSMQ入門一
            //創建消息隊列,默認存儲路徑:C:\Windows\System32\msmq\storage
            if (MessageQueue.Exists(@".\Private$\HelloMSMQ"))
                MessageQueue.Delete(@".\Private$\HelloMSMQ");   //刪除消息隊列HelloMSMQ
            if (MessageQueue.Exists(@".\Private$\WorldMSMQ"))
                MessageQueue.Delete(@".\Private$\WorldMSMQ");   //刪除消息隊列WorldMSMQ

            MessageQueue mqHello = MessageQueue.Create(@".\Private$\HelloMSMQ");
            MessageQueue mqWorld = MessageQueue.Create(@".\Private$\WorldMSMQ");

            //發送消息
            mqHello.Send("Hi World,I am Hello.", "mqHello1");
            mqHello.Send("Are you free?", "mqHello2");
            mqWorld.Send("Hi Hello,I am World.", "mqWorld1");
            mqWorld.Send("I guess I'll be free.", "mqWorld2");

            //返回本機所有私有隊列的消息
            foreach (MessageQueue item in MessageQueue.GetPrivateQueuesByMachine("cx168"))
            {
                item.Formatter = new XmlMessageFormatter(new string[] { "System.String" });
                Message[] messages = item.GetAllMessages();
                foreach (Message message in messages)
                {
                    Console.WriteLine($"Label: {message.Label} Body: {message.Body}");
                }
            }

            //返回指定隊列的消息
            if (MessageQueue.Exists(@".\Private$\HelloMSMQ"))
            {
                using (MessageQueue theOne = new MessageQueue(@".\Private$\HelloMSMQ"))
                {
                    Console.WriteLine();

                    //設置消息隊列格式化器
                    theOne.Formatter = new XmlMessageFormatter(new string[] { "System.String" });
                    //接受但不刪除消息
                    Message msg = mqHello.Peek();
                    Console.WriteLine($"Label: {msg.Label} Body: {msg.Body}");
                    //接受並刪除消息
                    msg = mqHello.Receive();
                    Console.WriteLine($"Label: {msg.Label} Body: {msg.Body}");
                    msg = mqHello.Peek();
                    Console.WriteLine($"Label: {msg.Label} Body: {msg.Body}");
                    //刪除所有消息
                    mqHello.Purge();
                    Console.WriteLine($"mqHello count: {mqHello.GetAllMessages().Count()}");
                }
            }

            Console.Read();
            #endregion
        }
    }

    運行結果如下:

 

    參考自:

    https://www.cnblogs.com/tenghoo/archive/2009/11/05/1596456.html

    https://www.cnblogs.com/shaoshun/p/3800208.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM