男女做爽爽爽网站-男女做羞羞高清-男女做爰高清无遮挡免费视频-男女做爰猛烈-男女做爰猛烈吃奶啪啪喷水网站-内射白浆一区

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C# 消息隊(duì)列(消息隊(duì)列的編程實(shí)現(xiàn))

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

?

本章內(nèi)容:
● 消息隊(duì)列概述
● 消息隊(duì)列體系結(jié)構(gòu)
● 消息隊(duì)列管理工具
● 編程實(shí)現(xiàn)消息隊(duì)列
● 課程訂單示例應(yīng)用程序
● 消息隊(duì)列和WCF

消息隊(duì)列的編程實(shí)現(xiàn)

既然理解了消息隊(duì)列的體系結(jié)構(gòu)之后,就可以探討其編程了。下面幾節(jié)將學(xué)習(xí)如何創(chuàng)建和控制 隊(duì)列,如何發(fā)送和接收消息。

還要構(gòu)建一個(gè)小型課程訂單應(yīng)用程序,它由發(fā)送部分和接收部分組成。

創(chuàng)建消息隊(duì)列

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

調(diào)用 Create()方法之后,就可以修改隊(duì)列的屬性。例如,使用Label 屬性,把隊(duì)列的標(biāo)簽設(shè)置為 Demo Queue。示例程序把隊(duì)列的路徑和格式名寫到控制臺(tái)上。格式名用UUID 自動(dòng)創(chuàng)建,UUID 可 用于訪問(wèn)隊(duì)列,且無(wú)須服務(wù)器名:

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

創(chuàng)建隊(duì)列時(shí)需要管理權(quán)限。通常不希望應(yīng)用程序的用戶擁有管理權(quán)限。這就是隊(duì) 列通常用安裝程序創(chuàng)建原因.

查找隊(duì)列

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

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()方法是重載的。它的一個(gè)重載版本允許傳遞MessageQueueCriteria 類的一個(gè)實(shí) 例。利用這個(gè)類可以搜索在某個(gè)時(shí)刻之前或之后創(chuàng)建或修改的隊(duì)列,還可以查找隊(duì)列的類別、標(biāo)簽 或計(jì)算機(jī)名。

可以使用靜態(tài)方法GetPrivateQueuesByMachine()搜索私有隊(duì)列。這個(gè)方法返回指定系統(tǒng)中的所 有私有隊(duì)列。

打開(kāi)已知隊(duì)列

如果隊(duì)列名已知,就不需要搜索它。使用路徑或格式名就可以打開(kāi)隊(duì)列。路徑或格式名都在 MessageQueue 類的構(gòu)造函數(shù)中設(shè)置。

路徑名

路徑指定了打開(kāi)隊(duì)列需要的計(jì)算機(jī)名和隊(duì)列名。下面的代碼示例打開(kāi)本地主機(jī)上的 MyPublicQueue 隊(duì)列。為了確定隊(duì)列是否存在,可以使用靜態(tài)方法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");
            }
        }
    }
}

根據(jù)隊(duì)列的類型,在打開(kāi)隊(duì)列時(shí)需要不同的標(biāo)識(shí)符。下表 列出了指定類型的隊(duì)列名的語(yǔ)法。

image

在使用路徑名打開(kāi)公共隊(duì)列時(shí),需要傳遞計(jì)算機(jī)名。如果計(jì)算機(jī)名未知,則可以使用格式名代 替。私有隊(duì)列的路徑名只能在本地系統(tǒng)上使用,必須使用格式名遠(yuǎn)程訪問(wèn)私有隊(duì)列。

格式名

除了路徑名之外,還可以使用格式名打開(kāi)隊(duì)列。格式名用于在Active Directory 中搜索隊(duì)列,獲 得隊(duì)列所在的主機(jī)。在斷開(kāi)連接的環(huán)境下,在發(fā)送消息時(shí)隊(duì)列不能到達(dá),此時(shí)就需要使用格式名:

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

格式名還有一些其他用途。它可以用于打開(kāi)私有隊(duì)列,并指定要使用的協(xié)議:
要 訪 問(wèn) 私有隊(duì)列, 必須給構(gòu)造函數(shù)傳遞字符串 FormatName:PRIVATE=MachineGUID\QueueNumber。在創(chuàng)建隊(duì)列時(shí),會(huì)生成私有隊(duì)列的隊(duì) 列號(hào)。隊(duì)列號(hào)在\System32\msmq\storage\lqs 目錄下。
使用 FormatName:DIRECT=Protocol:MachineAddress\QueueName,可以指定用于發(fā)送消息的 協(xié)議。Message Queuing 3.0 及以后版本支持HTTP 協(xié)議。

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

發(fā)送消息

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

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

消息格式化程序

消息傳輸給隊(duì)列的格式取決于格式化程序。MessageQueue 類有一個(gè)Formatter 屬性,通過(guò)它可 以指定格式化程序。默認(rèn)的格式化程序XmlMessageFormatter 會(huì)用XML 語(yǔ)法格式化消息,如前面的 例子所示。 消息格式化程序?qū)崿F(xiàn)IMessageFormatter 接口。System.Messaging 名稱空間中有3 個(gè)消息格式化 程序: XmlMessageFormatter 是默認(rèn)的格式化程序,它使用XML 序列化對(duì)象,XML 格式的內(nèi)容詳。

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

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

發(fā)送復(fù)雜的消息

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

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

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

接收消息

要讀取消息,也可以使用MessageQueue 類。通過(guò)Receive()方法可以讀取一條消息,再將該消 息從隊(duì)列中刪除。如果使用不同的優(yōu)先級(jí)發(fā)送消息,就讀取優(yōu)先級(jí)最高的消息。讀取優(yōu)先級(jí)相同的 消息時(shí),第一條發(fā)送的消息不一定是第一條讀取的消息,因?yàn)橄⒃诰W(wǎng)絡(luò)中的傳遞順序無(wú)法保證。 要保證發(fā)送順序和讀取順序相同,可以使用事務(wù)消息隊(duì)列。

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

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

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()方法將同步執(zhí)行,如果隊(duì)列中沒(méi)有消息,它就會(huì)等待隊(duì)列中有消息時(shí)再執(zhí)行。

枚舉消息

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

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 類實(shí)現(xiàn) IEnumerator 接口,但它有更多功能。實(shí)現(xiàn)IEnumerable 接口,就表示不從隊(duì)列中刪除消息。 MessageEnumerator 類的RemoveCurrent()方法可以從枚舉器的當(dāng)前光標(biāo)位置刪除消息。

在下面的例子中,使用MessageQueue 類的GetMessageEnumerator()方法訪問(wèn)MessageEnumerator 類。通過(guò)MessageEnumerator 類的MoveNext()方法,可以逐條查看消息。MoveNext()方法重載為允 許把一個(gè)時(shí)間段作為參數(shù)。這是使用這個(gè)枚舉器的一個(gè)主要優(yōu)點(diǎn)?,F(xiàn)在,線程可以在指定的時(shí)間段 內(nèi)等待消息到達(dá)隊(duì)列,之后就不等待了。IEnumerator 接口定義的Current 屬性返回消息的一個(gè)引用:

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()方法會(huì)等到隊(duì)列中的消息可以讀取為止。為了避免阻礙線程的執(zhí) 行,可以在Receive()方法的一個(gè)重載版本中指定一個(gè)超時(shí)期限。要在超時(shí)后讀取隊(duì)列中的消息,必 須再次調(diào)用Receive()方法。除了輪詢消息外,還可以調(diào)用BeginReceive()異步方法。在使用 BeginReceive()開(kāi)始異步讀取消息之前,應(yīng)設(shè)置ReceiveCompleted 事件。ReceiveCompleted 事件需要 ReceiveCompletedEventHandler 委托,在消息到達(dá)隊(duì)列并可以讀取時(shí)該委托引用要調(diào)用的方法。在下 面的例子中,把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()處理程序方法需要兩個(gè)參數(shù)。第一個(gè)參數(shù)是MessageQueue 事件源。第二個(gè)參 數(shù)是ReceiveCompletedEventArgs 類型,它包含消息和異步結(jié)果。在下面的例子中,調(diào)用隊(duì)列中的 EndReceive()方法,以獲得異步方法的結(jié)果,即消息:

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 編輯過(guò)
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 天美传媒MV视频中文字幕 | 性欧美老人牲交xxxxx视频 | 国产精品综合av一区二区国产 | 午夜福利免费一区二区 | 精品水蜜桃久久久久久久 | 国产成人精品午夜福利v免 国产成人精品午夜福利在线播放 | 国产亚洲精品久久久久久白晶晶 | 1区2区3区4区产品不卡码网站 | 久久精品国产成人午夜福利 | 婷婷丁香五月激情综合站 | 麻豆精品无人区码一二三区别:解锁创作自由与合作 | 欧美日韩国产另类激情图区 | 艳妇乳肉豪妇荡乳 | 久久免费久久 | 国产精品不久影院 | 精品国产一区二区三区久久影院 | 国产av一区二区三区香蕉 | 亚洲精品综合欧美一区二区 | 成人免费视频一区二区三区 | 国产AV午夜精品一区二区三区 | 成人亚洲A片V一区二区三区日本 | 中文人妻AV久久人妻水密桃 | 国内精品久久久一 | 在线91精品亚洲网站精品成人 | 天天婷婷 | 精品亚洲一区二区在线播放 | 2024国内在线精品视频 | 色视频综合无码一区二区三区 | 国产精品无码AV天天爽色欲 | av天堂午夜精品一 | 国产一级视频在线 | 国产精品一区二区三区免费 | 亚洲一区日韩无码 | 成人无码A片一区二区三区免 | 国产午夜男女爽爽爽爽爽 | 18禁黄网站禁片免费观看国产 | 国产69久久精品成人看 | 少妇人妻无码精品视频 | 99热久久这里只有精品 | 国产无人区卡一卡二卡乱码 | 国产人妻人伦精品熟女 |