无码国模产在线观看免费-无码国内精品久久人妻-无码国内精品久久综合88-无码国内精品人妻少妇-无码国内精品人妻少妇蜜桃视频-无码国语中文在线播放

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

C# 消息隊列(消息隊列的編程實現)

admin
2025年4月24日 0:36 本文熱度 68

?

本章內容:
● 消息隊列概述
● 消息隊列體系結構
● 消息隊列管理工具
● 編程實現消息隊列
● 課程訂單示例應用程序
● 消息隊列和WCF

消息隊列的編程實現

既然理解了消息隊列的體系結構之后,就可以探討其編程了。下面幾節將學習如何創建和控制 隊列,如何發送和接收消息。

還要構建一個小型課程訂單應用程序,它由發送部分和接收部分組成。

創建消息隊列

創建消息隊列 前面了解了如何使用Computer Management 實用程序創建消息隊列。消息隊列還可以用 MessageQueue 類的Create()方法以編程方式創建。
在 Create()方法中,必須傳遞新隊列的路徑。路徑包括隊列所在主機的名稱和隊列的名稱。在下 面的例子中,要在本地主機上創建MyNewPublicQueue 隊列。為了創建私有隊列,路徑名必須包含 Private\MyNewPrivateQueue。

調用 Create()方法之后,就可以修改隊列的屬性。例如,使用Label 屬性,把隊列的標簽設置為 Demo Queue。示例程序把隊列的路徑和格式名寫到控制臺上。格式名用UUID 自動創建,UUID 可 用于訪問隊列,且無須服務器名:

using System;
using System.Messaging;
namespace Wrox.ProCSharp.Messaging
{
class Program
{
    static void Main()
    {
        using (var queue = MessageQueue.Create(@".\MyNewPublicQueue"))
        {
            queue.Label = "Demo Queue";
            Console.WriteLine("Queue created:");
            Console.WriteLine("Path: {0}", queue.Path);
            Console.WriteLine("FormatName: {0}", queue.FormatName);
        }
    }
  }
}

創建隊列時需要管理權限。通常不希望應用程序的用戶擁有管理權限。這就是隊 列通常用安裝程序創建原因.

查找隊列

路徑名和格式名可以用于標識隊列。要查找隊列,必須區分公共隊列和私有隊列。公共隊列在 Active Directory 中發布。對于這些隊列,無須知道它們所在的系統。只有在己知隊列所在系統私有 隊列名稱時才能找到私有隊列。
在 Active Directory 域中搜索隊列的標簽、類別或格式名,就可以找到公共隊列。還可以獲得計算 機上的所有隊列。MessageQueue 類的靜態方法GetPublicQueuesByLabel()、GetPublicQueuesByCategory() 和GetPublicQueuesByMachine()可以搜索隊列。GetPublicQueues()方法返回包含域中所有公共隊列的 數組。

using System;
using System.Messaging;
namespace Wrox.ProCSharp.Messaging
{
    class Program
    {
      static void Main()
      {
          foreach (var queue in MessageQueue.GetPublicQueues())
          {
              Console.WriteLine(queue.Path);
          }
      }
    }
}

GetPublicQueues()方法是重載的。它的一個重載版本允許傳遞MessageQueueCriteria 類的一個實 例。利用這個類可以搜索在某個時刻之前或之后創建或修改的隊列,還可以查找隊列的類別、標簽 或計算機名。

可以使用靜態方法GetPrivateQueuesByMachine()搜索私有隊列。這個方法返回指定系統中的所 有私有隊列。

打開已知隊列

如果隊列名已知,就不需要搜索它。使用路徑或格式名就可以打開隊列。路徑或格式名都在 MessageQueue 類的構造函數中設置。

路徑名

路徑指定了打開隊列需要的計算機名和隊列名。下面的代碼示例打開本地主機上的 MyPublicQueue 隊列。為了確定隊列是否存在,可以使用靜態方法MessageQueue.Exists():

using System;
using System.Messaging;
namespace Wrox.ProCSharp.Messaging
{
    class Program
    {
        static void Main()
        {
            if (MessageQueue.Exists(@".\mynewpublicqueue"))
            {
                var queue = new MessageQueue(@".\mynewpublicqueue");
                //...
            }
            else
            {
                Console.WriteLine("Queue .\MyPublicQueue not existing");
            }
        }
    }
}

根據隊列的類型,在打開隊列時需要不同的標識符。下表 列出了指定類型的隊列名的語法。

image

在使用路徑名打開公共隊列時,需要傳遞計算機名。如果計算機名未知,則可以使用格式名代 替。私有隊列的路徑名只能在本地系統上使用,必須使用格式名遠程訪問私有隊列。

格式名

除了路徑名之外,還可以使用格式名打開隊列。格式名用于在Active Directory 中搜索隊列,獲 得隊列所在的主機。在斷開連接的環境下,在發送消息時隊列不能到達,此時就需要使用格式名:

MessageQueue queue = new MessageQueue(
@"FormatName:PUBLIC=09816AFF-3608-4c5d-B892-69754BA151FF");

格式名還有一些其他用途。它可以用于打開私有隊列,并指定要使用的協議:
要 訪 問 私有隊列, 必須給構造函數傳遞字符串 FormatName:PRIVATE=MachineGUID\QueueNumber。在創建隊列時,會生成私有隊列的隊 列號。隊列號在\System32\msmq\storage\lqs 目錄下。
使用 FormatName:DIRECT=Protocol:MachineAddress\QueueName,可以指定用于發送消息的 協議。Message Queuing 3.0 及以后版本支持HTTP 協議。

FormatName:DIRECT=OS:MachineName\QueueName 是使用格式名指定隊列的另一種方式。 此時不需要指定協議,但仍可以使用計算機名和格式名。

發送消息

可以使用MessageQueue 類的Send()方法給隊列發送消息。作為參數傳遞給Send()方法的對象序 列化到相關聯的隊列上。Send()方法是重載的,這樣才能傳遞標簽和MessageQueueTransaction 對象。 Message Queuing 的事務行為在后面論述。 下面的代碼示例先檢查隊列是否存在,如果不存在,就創建一個隊列。接著打開隊列,使用Send() 方法給隊列發送Sample Message 消息。 路徑名給服務器名指定“.”,表示它是本地系統。私有隊列的路徑名只能在本地使用。

using System;
using System.Messaging;
namespace Wrox.ProCSharp.Messaging
{
    class Program
    {
        static void Main()
        {
            try
            {
                if (!MessageQueue.Exists(@".\Private$\MyPrivateQueue"))
                {
                    MessageQueue.Create(@".\Private$\MyPrivateQueue");
                }
                var queue = new MessageQueue(@".\Private$\MyPrivateQueue");
                queue.Send("Sample Message", "Label");
          }
          catch (MessageQueueException ex)
          {
              Console.WriteLine(ex.Message);
          }
      }
  }
}

消息格式化程序

消息傳輸給隊列的格式取決于格式化程序。MessageQueue 類有一個Formatter 屬性,通過它可 以指定格式化程序。默認的格式化程序XmlMessageFormatter 會用XML 語法格式化消息,如前面的 例子所示。 消息格式化程序實現IMessageFormatter 接口。System.Messaging 名稱空間中有3 個消息格式化 程序: XmlMessageFormatter 是默認的格式化程序,它使用XML 序列化對象,XML 格式的內容詳。

使用 BinaryMessageFormatter,可以用二進制格式對消息進行序列化。這些消息比使用XML 格式化的消息短。

ActiveXMessageFormatter 是一個二進制格式化程序,這樣可以用COM 對象讀寫消息。使 用這個格式化程序,可以用.NET 類把消息寫入隊列中,使用COM 對象從隊列中讀取消息, 反之亦然。

發送復雜的消息

除了傳遞字符串之外,還可以給MessageQueue 類的Send()方法傳遞對象。雖然該類的類型必 須滿足一些特定的要求,但它們取決于格式化程序。

對于二進制格式化程序,該類必須用[Serializable]屬性序列化。使用.NET 運行庫的序列化功能, 序列化所有字段(包括私有字段)。實現ISerializable 接口就可以定義自定義序列化。

XML 序列化在使用XML 格式化程序時進行。在XML 序列化過程中,會序列化所有公共字段 和屬性。使用System.Xml.Serialization 名稱空間中的屬性可以影響XML 序列化。

接收消息

要讀取消息,也可以使用MessageQueue 類。通過Receive()方法可以讀取一條消息,再將該消 息從隊列中刪除。如果使用不同的優先級發送消息,就讀取優先級最高的消息。讀取優先級相同的 消息時,第一條發送的消息不一定是第一條讀取的消息,因為消息在網絡中的傳遞順序無法保證。 要保證發送順序和讀取順序相同,可以使用事務消息隊列。

在下面的例子中,要從私有隊列MyPrivateQueue 中讀取一條消息。之前把一個簡單的字符串傳 遞給該消息。在使用XmlMessageFormatter 格式化程序讀取消息時,必須把要讀取的對象的類型傳 遞給該格式化程序的構造函數。在本例中,將System.String 類型傳遞給XmlMessageFormatter 的構 造函數的參數數組。這個構造函數可以接收一個String 數組,該數組包含要作為字符串傳遞的類型; 也可以接收一個Type 數組。

用 Receive()方法讀取消息,再把消息正文寫入控制臺中:

using System;
using System.Messaging;
namespace Wrox.ProCSharp.Messaging
{
    class Program
    {
        static void Main()
        {
            var queue = new MessageQueue(@".\Private$\MyPrivateQueue");
            queue.Formatter = new XmlMessageFormatter(
new string[] {"System.String"});
            Message message = queue.Receive();
            Console.WriteLine(message.Body);
      }
  }
}

Receive()方法將同步執行,如果隊列中沒有消息,它就會等待隊列中有消息時再執行。

枚舉消息

除了使用 Receive()方法逐條消息地讀取之外,還可以使用枚舉器遍歷所有消息。因為 MessageQueue 類實現IEnumerable 接口,所以可以在foreach 語句中使用。使用迭代器時,雖然消息 不會從隊列中刪除,但可以查看消息從而獲得它們的內容:

var queue = new MessageQueue(@".\Private$\MyPrivateQueue");
queue.Formatter = new XmlMessageFormatter(
new string[] {"System.String"});
foreach (Message message in queue)
{
    Console.WriteLine(message.Body);
}

除了使用IEnumerable 接口外,還可以使用MessageEnumerator 類。雖然MessageEnumerator 類實現 IEnumerator 接口,但它有更多功能。實現IEnumerable 接口,就表示不從隊列中刪除消息。 MessageEnumerator 類的RemoveCurrent()方法可以從枚舉器的當前光標位置刪除消息。

在下面的例子中,使用MessageQueue 類的GetMessageEnumerator()方法訪問MessageEnumerator 類。通過MessageEnumerator 類的MoveNext()方法,可以逐條查看消息。MoveNext()方法重載為允 許把一個時間段作為參數。這是使用這個枚舉器的一個主要優點。現在,線程可以在指定的時間段 內等待消息到達隊列,之后就不等待了。IEnumerator 接口定義的Current 屬性返回消息的一個引用:

var queue = new MessageQueue(@".\Private$\MyPrivateQueue");
queue.Formatter = new XmlMessageFormatter(
new string[] {"System.String"});
using (MessageEnumerator messages = queue.GetMessageEnumerator())
{
    while (messages.MoveNext(TimeSpan.FromMinutes(30)))
    {
        Message message = messages.Current;
        Console.WriteLine(message.Body);
    }
}

異步讀取

MessageQueue 類的Receive()方法會等到隊列中的消息可以讀取為止。為了避免阻礙線程的執 行,可以在Receive()方法的一個重載版本中指定一個超時期限。要在超時后讀取隊列中的消息,必 須再次調用Receive()方法。除了輪詢消息外,還可以調用BeginReceive()異步方法。在使用 BeginReceive()開始異步讀取消息之前,應設置ReceiveCompleted 事件。ReceiveCompleted 事件需要 ReceiveCompletedEventHandler 委托,在消息到達隊列并可以讀取時該委托引用要調用的方法。在下 面的例子中,把MessageArrived()方法傳遞給ReceivedCompletedEventHandler 委托:

var queue = new MessageQueue(@".\Private$\MyPrivateQueue");
queue.Formatter = new XmlMessageFormatter(
new string[] { "System.String" });
queue.ReceiveCompleted += MessageArrived;
queue.BeginReceive();
// thread does not wait

MessageArrived()處理程序方法需要兩個參數。第一個參數是MessageQueue 事件源。第二個參 數是ReceiveCompletedEventArgs 類型,它包含消息和異步結果。在下面的例子中,調用隊列中的 EndReceive()方法,以獲得異步方法的結果,即消息:

public static void MessageArrived(object source, ReceiveCompletedEventArgs e)
{
    MessageQueue queue = (MessageQueue)source;
    Message message = queue.EndReceive(e.AsyncResult);
    Console.WriteLine(message.Body);
}


閱讀原文:原文鏈接


該文章在 2025/4/24 10:02:21 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 免费看成人的网站软件 | 日韩视频国产 | 国产成人禁片在线观看 | 99久久国产精品视频 | 国产欧美熟妇另类久久久 | 国产精品无码制服丝袜 | a级国产高清美女理论片 | 国产1女3男4p精品久久 | 无码人妻一区二区三区蜜桃手机版 | 久久国内精品自在自线 | 韩国三级日本三级香港三级黄 | 人马畜禽CORPORATION | 国产欧美日韩精品高清二区综合区 | 在线观看国产一区二区三区 | 久久国产精品久久久久久 | 果冻传媒91制片潘甜甜七夕古装仙侠 | 好紧再快点好深好爽视频 | 精品国产女人爽到喷水 | 99久久九九国产精品国产 | 综合国产 | 一夜色鲁干就色 | 成人性三级欧美在线观看 | 久久国产一级毛片一区二区 | 动漫精品一区二区三 | 天天草天天流 | 国产成人午夜精品一区二区 | 国产美女视频一区二区二三区 | 欧美日韩国产高清 | 精品在线视频一区 | 国产精品人妻一区二区三区四 | 国产午夜精品免费一区二区三区 | 日韩一区二区三区射精百度 | 秋秋影视午夜福利高清 | 秋霞电影网视频一区二区三区香港韩国日本三级 | 妺妺窝人体色WWW网站 | 人妻日本无中文字幕无码 | 日韩一区二区精品观看 | 日韩欧美人妻中文字幕一区二区 | 99热精品久久只有 | 91麻豆精品国产自产在线观看一区 | 国产欧美一区二区在线播放 |