c#利用消息隊列解決進程間信息交互_第1頁
c#利用消息隊列解決進程間信息交互_第2頁
c#利用消息隊列解決進程間信息交互_第3頁
c#利用消息隊列解決進程間信息交互_第4頁
c#利用消息隊列解決進程間信息交互_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、使用微軟消息隊列實現(xiàn)C#進程間通信2008-07-25來源:網(wǎng)絡(luò)顧名思義,微軟消息隊列(MSMQ)是一種給隊列發(fā)送消息以便稍后進行處理的方法。消息由 一個“Producer”(生產(chǎn)者)應(yīng)用程序發(fā)送出去,再由一個“Consumer”(消費者)應(yīng)用程序返回。這兩個應(yīng)用程序可以在同一臺機器上,在整個網(wǎng)絡(luò)中,或甚至是位于并不總是連接在一起的不同 機器上。MSMQ具有故障保險特性,因為如果第一次傳送失敗,它會重新發(fā)送消息。這樣可保證 你的應(yīng)用程序消息到達它們的目的地。我將應(yīng)用一個叫做“TechRepublic”的隊列。當(dāng)你運行本文下載版本中的樣本實例時,如果這個隊 列不存在,它會自動建立。在前面的一篇文

2、章中,Zach Smith說明了如何使用IPC通道在同一臺機器上的兩個進程間通信。 他將在本文中說明如何在同一臺機器或網(wǎng)絡(luò)上的應(yīng)用程序間實現(xiàn)進程間通信。訪問MSMQ通過.NET訪問隊列由System.Messaging.MessageQueue對象完成。列表A說明了如何在一臺名 為“SRV-MESSAGING”的計算機上訪問TechRepublic隊列。列表AMessageQueue queue =new MessageQueue(SRV-MESSAGINGTechRepublic);注:要應(yīng)用這個對象,你必須在你的項目中添加一個參考?,F(xiàn)在我們有了一個MessageQueue對象,這個對象為你

3、提供與隊列交互需要的所有功能。如果隊列不存在,你可以調(diào)用MessageQueue對象的靜態(tài)Create方法編程建立隊列。列表B中的 代碼說明如何檢查隊列是否存在,建立隊列或給隊列添加一個參考。列表BMessageQueue queue = null;string queueName = SRV-MESSAGINGTechRepublic;if (MessageQueue.Exists(queueName)queue = newMessageQueue(queueName);elsequeue = MessageQueue.Create(queueName, false);改寫隊列改寫隊列時,用

4、到MessageQueue.Send方法。列表C舉例說明如何向TechRepublic隊列發(fā)送一 條消息。列表Cqueue.Send(My message body, Message Label);在這個例子中,我們給TechRepublic隊列發(fā)送一條正文為“My message body”的消息,并對這個 消息應(yīng)用了一個“Message Label”標(biāo)簽。消息標(biāo)簽允許你不需閱讀消息正文就可以分割消息。如果從 計算機管理控制臺中查看隊列,還可在“隊列消息”部分看到這些標(biāo)簽。讀取隊列可以使用幾種方法從隊列中讀取消息。最常見的情況是從隊列中取出所有消息,然后一次性處理 它們。這時要調(diào)用Messa

5、geQueue.GetAllMessages方法。列表D舉例說明如何應(yīng)用這個方法。列表DSystem.Messaging.Message messages = queue.GetAllMessages();foreach (System.Messaging.Message message in messages)你也可以用 GetMessageEnumerator2 方法代替上面的 MessageQueue.GetAllMessages 方法。雖然 這兩個方法的用法類似,但GetMessageEnumerator2只能向前(forward-only)o對于非常龐大的隊 列,則應(yīng)用使用這個方法,

6、而不是MessageQueue.GetAllMessages方法。這是因為GetAllMessages方法領(lǐng)取所有消息,把它們保存在當(dāng)?shù)貎?nèi)存中;而 GetMessageEnumerator2方法只領(lǐng)取當(dāng)前消息在本地保存,在調(diào)用MoveNext時才領(lǐng)取下一條消息。 列表E舉例說明了 GetMessageEnumerator2方法的用法。這段代碼檢查隊列中的每一條消息,再刪 除它。列表EMessageEnumerator enumerator = queue.GetMessageEnumerator2();while (enumerator.MoveNext()enumerator.RemoveC

7、urrent();在使用GetMessageEnumerator2方法時,還要考慮另外一個問題,即你要訪問隊列中增加的任何 新消息,即使它們是在你調(diào)用GetMessageEnumerator2后再增加的。這假定新消息被添加到隊列末 尾。如果你只希望返回隊列中的第一條消息,你應(yīng)該使用MessageQueue.Receive方法。這個方法會 領(lǐng)取隊列中的第一條消息,在這個過程中將它從隊列中刪除。由于消息在讀取的時候被刪除,你可 以確保你的進程是唯一收到消息的進程。Receive方法的應(yīng)用實例如列表F所示。列表FSystem.Messaging.Message message = queue.Rec

8、eive();可以用Peek方法代替Receive方法。Peek方法像Receive方法一樣領(lǐng)取隊列中的第一條消息; 但是,它在隊列中保留消息備份。這允許你從隊列中刪除消息之前檢查消息內(nèi)容。Peek的語法與Receive 類似。列表GSystem.Messaging.Message message = queue.Peek();發(fā)送/接收序列化對象雖然給隊列發(fā)送文本的功能非常有用,但隊列還允許你發(fā)送可序列化對象。這意味著你可以建立 一個自定義的.NET類,實例化它的一個實例,將其發(fā)送給隊列以便其它應(yīng)用程序使用。要完成這 個過程,首先得使用XML Serializer序列化被發(fā)送的對象,然后對序

9、列化對象放到消息的正文中。例如,假設(shè)我們希望給TechRepublic消息隊列發(fā)送以下對象(列表H):列表HSerializable。publicclassMessageContentprivateDateTime _creationDate = DateTime.Now;privatestring _messageText;public MessageContent()public MessageContent(string messageText)給隊列發(fā)送這個對象的一個實例只需簡單調(diào)用MessageQueue.Send方法,并把一個對象實例作為 參數(shù)提交給這個方法。列表I說明了這種情況。

10、列表IMessageContent message = newMessageContent(Hello world!);queue.Send(message, Sample Message);如你所見,上面的代碼類似于我們前面發(fā)送正文為一個字符串的消息時使用的代碼。接收一個包 含序列化對象的消息更加困難一些。我們需要告訴消息它包含哪種對象。為向消息指出它包含哪種對象,我們必須建立消息的格式化器(formatter)。給消息的Formatter 屬性指定一個System.Messaging.XmlMessageFormatter對象即可建立格式化器。由于我們的消息包 含一個MessageCont

11、ent對象,我們希望為它配置XmlMessageFormatter。列表Jmessage.Formatter =new System.Messaging.XmlMessageFormatter(newType1 typeof(MessageContent) );既然我們已經(jīng)給消息指定了一個格式化器,我們可以從消息中提取MessageContent對象。但在 這之前,我們需要把message.Body屬性的返回值分配給一個MessageContent對象。列表KMessageContent content = (MessageContent)message.Body;在這個例子中,“conten

12、S”量是我們向隊列發(fā)送的原始MessageContent對象的序列化版本,我們 可以訪問原始對象的所有屬性和值。設(shè)定消息優(yōu)先級別在正常情況下,隊列中的消息以先進先出的形式被訪問。這表示如何你先發(fā)送消息A,再發(fā)送消 息B,那么隊列將首先返回消息A,然后才是消息B。在多數(shù)情況下,這樣處理沒有問題。但是, 有時,由于一條消息比其它消息更加重要,你希望將它提到隊列前面。要實現(xiàn)這種功能,你就需要 設(shè)定消息優(yōu)先級別。一條消息的優(yōu)先級別由它的Message.Priority屬性值決定。下面是這個屬性的所有有效值(全部 來自MessagePriority的列舉類型):最高(Highest)非常高(VeryHi

13、gh)高(High)高于正常級別(AboveNormal)正常(Normal)低(Low)非常低(VeryLow)最低(Lowest)消息在隊列中的位置由它的優(yōu)先級別決定例如,假如隊列中有四條消息,兩條消息的優(yōu)先級 別為“正?!保∟ormal),另兩條為“高”(High)。則隊列中消息排列如下:High Priority A這是發(fā)送給隊列的第一條“高”優(yōu)先級消息。High Priority B這是發(fā)送給隊列的第二條高”優(yōu)先級消息。Normal Priority A這是發(fā)送隊列的第一條“正?!眱?yōu)先級消息。Normal Priority B這是發(fā)送隊列的第二條“正?!眱?yōu)先級消息。根據(jù)這個順序,如果

14、我們給隊列發(fā)送另一條“最高”優(yōu)先級的消息,它將位于隊列的頂部。如果需要使用消息優(yōu)先級功能,你必須修改發(fā)送消息的代碼。因為Message對象的構(gòu)造器沒有指 定消息優(yōu)先級別的功能,你必須實例化一個Message對象,并在將它發(fā)送給隊列之前給它設(shè)定相應(yīng) 的屬性。列表L中的代碼說明如何設(shè)定優(yōu)先級別,并給隊列發(fā)送一條“最高”優(yōu)先級別的消息。列表L/Instantiate the queueMessageQueue queue = newMessageQueue(queueName);/Create a XmlSerializer for the object type were sending.XmlS

15、erializer serializer = newXmlSerializer(typeof(MessageContent);/Instantiate a new message.System.Messaging.Message queueMessage =new System.Messaging.Message();/Set the priority to Highest.queueMessage.Priority = MessagePriority.Highest;/Create our MessageContent object.MessageContent messageContent

16、 =newMessageContent(Hello world - IMPORTANT!);/Serialize the MessageContent object into the queueMessage.serializer.Serialize(queueMessage.BodyStream, messageContent);/Send the message.queue.Send(queueMessage, HIGH PRIORITY);這段代碼和上面代碼的最明顯區(qū)別在于它使用了 XmlFormatter。它實際是可選的,列表L中的 代碼也可用列表M中的代碼代替。列表M/Instant

17、iate a new message.System.Messaging.Message queueMessage =new System.Messaging.Message();/Set the priority to Highest.queueMessage.Priority = MessagePriority.Highest;/Create our MessageContent object.MessageContent messageContent =newMessageContent(Hello world - IMPORTANT!);/Set the body as the messageContent object.queueMessage.Body = messageContent;/Send the message.queue.Send(queueMessage, HIGH PRIORITY);這段代碼執(zhí)行和列表L中的代碼相同的任務(wù),但代碼更少。應(yīng)用輸入消費者請求是MSMQ功能

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論