C- 消息隊列之 MSMQ

首先說一下,消息隊列 (MSMQ Microsoft Message Queuing) 是 MS 提供的服務,也就是 Windows 操作系統的功能,並不是. Net 提供的。

消息隊列(MSMQ)技術使得運行於不同時間的應用程序能夠在各種各樣的網絡和可能暫時脫機的系統之間進行通信。

應用程序將消息發送到隊列,並從隊列中讀取消息。

下圖演示了消息隊列如何保存由多個發送應用程序生成的消息,並被多個接收應用程序讀取。

消息一旦發送到隊列中,便會一直存在,即使發送的應用程序已經關閉。

 MSMQ 服務默認是關閉的,(Window7 及以上操作系統) 按以下方式打開

1、打開運行,輸入 "OptionalFeatures",鉤上 Microsoft Message Queue(MSMQ) 服務器。

消息隊列(Message Queue)是一種使用隊列(Queue)作爲底層存儲數據結構,可以用於解決不同進程與應用程序之間通訊的分佈式消息容器,也可以稱爲消息中間件。

目前比較常用的消息隊列有 ActiveMQ、RabbitMQ、MSMQ ,Kafka、RocketMQ、Redis 等。

唯一的區別在於入隊列的時候稱爲生產者,出隊列的時候稱爲消費者。

我理解的 MSMQ

系統的消息隊列,爲我們提供了 3 種隊列傳出隊列,專用隊列和系統隊列,而用戶能自由創建的只有專用隊列。我們可以嘗試創建一個專用隊列,"右擊" 專用隊列,再點擊 "新建",得到新增界面如下圖。由於我們創建的是專用隊列,所以在隊列命名上面顯示的添加 "private$", 另一個事務複選框表示我們要創建的是隊列是否爲事務隊列,這個在稍後我會詳細的解釋

 

我在專用隊列裏面添加一個叫 "shaoshun" 的專用隊列,在專用隊列文件夾下面就可以找到,如圖

消息

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

隊列

  在前面,我們通過手動創建了一個專用隊列。我們知道隊列分事務性隊列和非事務性隊列,默認創建的是非事務性隊列。當我們勾選事務性複選框,我們就會創建事務性隊列,那麼什麼是事務性隊列呢? 事務性隊列將消息保存在磁盤上,實現了持久化,也就是說當我們關機,斷電後,下次再啓動機器,我們的消息依然保存在隊列裏面,而非事務性隊列則將消息保存在內存中,也就是說我重啓電腦後,隊列裏面的消息將不存在了。

     隊列支持事務操作,當我們把對多個消息的接收操作納入一個事務中,那麼只要有一個消息接收不成功,隊列將拋棄前面接收的所有消息,實現事務回滾。隊列事務同時支持消息按順序接收與發送。

實例:

 需要先引用 System.Messaging.dll

#region 消息隊列
using System;
using System.Collections.Generic;
using System.Linq;
using System.Messaging;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace test
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 創建消息隊列  
            const string queueName = @".\Private$\jiyiqin";
            MessageQueue mq = null;
            if (!MessageQueue.Exists(queueName))// 如果指定的路徑queueName中不存在隊列,那麼在該路徑,即queueName中創建一個消息隊列。jiyiqin就是你想要創建消息隊列的名字
            {
                mq = MessageQueue.Create(queueName);//創建名稱jiyiqin的消息隊列的實例。
                Console.WriteLine("創建消息隊列完成:" + queueName);
            }
            else  //如果消息隊列jiyiqin已經存在,那麼創建該消息隊列的一個實例
            {
                mq = new MessageQueue(queueName);//創建名稱jiyiqin的消息隊列的實例。
            }
            mq.SetPermissions("Administrator", MessageQueueAccessRights.FullControl);
            mq.SetPermissions("ANONYMOUS LOGON", MessageQueueAccessRights.FullControl);
            mq.SetPermissions("Everyone", MessageQueueAccessRights.FullControl);
            #endregion
            #region 發送消息隊列
            string strTx = "123我";
            Message msgTx = new Message();
            msgTx.Body = strTx;
            msgTx.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
            mq.Send(msgTx);
            #endregion
            #region 接收消息隊列
            //接收到的消息對象
            Message msgRx = mq.Receive();
            //指定格式化程序
            msgRx.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
            //接收到的內容
            string strRx = msgRx.Body.ToString();
            System.Windows.Forms.MessageBox.Show(strRx);
            #endregion
        }
    }
}

需加微信交流羣的,請加小編微信號 zls20210502,切記備註 加羣,小編將會第一時間邀請你進羣!(目前①羣已滿 ,需要在②羣排隊等坑位)

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/rGSYrfvnYUz7yl4zJkh6Fg