ASP.NET中进行消息处理(MSMQ) 一
MSMQ是微軟消息隊列的英文縮寫。那么什么是消息隊列?這些介紹網(wǎng)上一大片這里就不多說了。本文對于大蝦級的人物來說這只是小玩意而已,對于初學者來說這文章還是有一定的幫助,希望路過的大蝦們別笑話我班門弄斧。一、MSMQ介紹和安裝消息隊列
????? 關(guān)于MSMQ詳細的介紹請大家向http://www.baidu.com/或http://www.g.cn/等專家咨詢。
????? 使用消息隊列的優(yōu)點:穩(wěn)定、消息優(yōu)先級、脫機能力以及安全性。
????? 消息隊列分為用戶創(chuàng)建的隊列(專用隊列)和系統(tǒng)隊列,用戶隊列分為,。我是Windows XP,看下圖所示(myQueue為自己創(chuàng)建的消息隊列,msmqtriggersnotifiations為通用隊列):
???? 對消息隊列有了簡單的了解后,使用MSMQ進行軟件開發(fā)需要安裝MSMQ,安裝完后就該進入實際的開發(fā)階段。具體的安裝過程就是在控制面板里“添加/刪除程序”下“添加/刪除Windows組件”,完成添加就OK。安裝完成后就可以通過交互界添加新的消息隊列,詳細如下圖:
????? 出了上面這種交互界面來創(chuàng)建MSMQ外,也可以通過編程來完成,.NET框架里的MessageQueue類下有一靜態(tài)方法Create,用來完成消息隊列的創(chuàng)建,其定義如下: ?1//
?2//?摘要:
?3//????在指定的路徑中創(chuàng)建非事務性“消息隊列”隊列。
?4//
?5//?參數(shù):
?6//???path:
?7//?????要創(chuàng)建的隊列的路徑。
?8//
?9//?返回結(jié)果:
10//?????表示新隊列的?System.Messaging.MessageQueue。
11public?static?MessageQueue?Create(string?path);
12//
13//?摘要:
14//?????在指定的路徑中創(chuàng)建事務性或非事務性“消息隊列”隊列。
15//
16//?參數(shù):
17//???transactional:
18//?????如果創(chuàng)建事務性隊列,為?true;如果創(chuàng)建非事務性隊列,則為?false。
19//
20//???path:
21//?????要創(chuàng)建的隊列的路徑。
22//
23//?返回結(jié)果:
24//?????表示新隊列的?System.Messaging.MessageQueue。
25public?static?MessageQueue?Create(string?path,?bool?transactional);
???? 實現(xiàn)消息隊列的創(chuàng)建簡單代碼(C#),創(chuàng)建一個名為"myQueue"的非事務性"消息隊列",如下:
二、創(chuàng)建、刪除和管理隊列
????? 在.NET環(huán)境下編寫Message Queue程序的前提就是需要先安裝MSMQ,本文之前已經(jīng)作了詳細的介紹。要開發(fā)MSMQ程序就必須學習一個很重要的類(MessageQueue),該類位于名稱空間System.Messageing下。其中有幾個常用的方法必須掌握:
? --Create方法:創(chuàng)建使用指定路徑的新消息隊列。
? --Delete方法:刪除現(xiàn)有的消息隊列。
? --Existe方法:查看指定消息隊列是否存在。
? --GetAllMessages()方法:得到隊列中的所有消息。
? --GetPublicQueues方法:在“消息隊列”網(wǎng)絡中定位消息隊列。
? --Peek/BeginPeek方法:查看某個特定隊列中的消息隊列,但不從該隊列中移出消息。
? --Receive/BeginReceive方法:檢索指定消息隊列中最前面的消息并將其從該隊列中移除。
? --Send方法:發(fā)送消息到指定的消息隊列。
? --Purge方法:清空指定隊列的消息。
??? 上述列舉的方法在此就不作詳細介紹,大家可以通過下面的示例程序中來體會他們各自的功能。三、發(fā)送和序列化消息?????MSMQ消息隊列中定義的消息由一個主體(body)和若干屬性構(gòu)成。消息的主體可以由文本、二進制構(gòu)成,根據(jù)需要還可以被加密。在MSMQ 中消息的大小不能夠超過4MB。發(fā)送消息是通過Send方法來完成的,需要一個Message參數(shù)。
1、發(fā)送消息:
?????步驟:連接隊列-->指定消息格式-->提供要發(fā)送的數(shù)據(jù)(主體)-->調(diào)用Send()方法將消息發(fā)送出去。詳細見后面的示例程序。
2、序列化消息:
???? 消息序列化可以通過.NET Framework附帶的三個預定義格式化程序來完成:
??? --? XMLMessageFormatter對象----MessageQueue組件的默認格式化程序設置。
??? --? BinaryMessageFormatter對象;
????--??ActiveXMessageFormatter對象;?
??? 由于后兩者格式化后的消息通常不能為人閱讀,所以我們經(jīng)常用到的是XMLMessageFormatter對象。該對象構(gòu)造方法有三種重載:
2public?XmlMessageFormatter(string[]?targetTypeNames);
3public?XmlMessageFormatter(Type[]?targetTypes);
如我們后面的示例程序中用到的序列化語句:
1//序列化為字符串2XmlMessageFormatter?formatter?=?new?XmlMessageFormatter(new?Type[]?{?typeof(string)?});
四、讀取和接收消息1、讀取消息:
??? 也就是從指定隊列中獲取消息,詳細請查看本文前面的關(guān)于消息操作的方法介紹。
2、接收消息有兩種方式:
??? --> 通過Receive方法--具體功能請返回本文前面有詳細介紹。
??? --> 通過Peek方法--具體功能請返回本文前面有詳細介紹。五、消息使用實例
?????通過上面一系列的介紹,了解了MessageQueue類和常用的方法后,下面我們通過一個簡單的示例程序來分析消息隊列的創(chuàng)建、發(fā)送消息以及接收消息等相關(guān)知識點:
1、通過Create方法創(chuàng)建使用指定路徑的新消息隊列
?2///?通過Create方法創(chuàng)建使用指定路徑的新消息隊列
?3///?</summary>
?4///?<param?name="queuePath"></param>
?5public?static?void?Createqueue(string?queuePath)
?6{
?7????try
?8????{
?9????????if?(!MessageQueue.Exists(queuePath))
10????????{
11????????????MessageQueue.Create(@".\private$\myQueue");
12????????}
13????????else
14????????{
15????????????Console.WriteLine(queuePath?+?"已經(jīng)存在!");
16????????}
17????}
18????catch?(MessageQueueException?e)
19????{
20????????Console.WriteLine(e.Message);
21????}
22}
2、連接消息隊列并發(fā)送消息到隊列
?2///?連接消息隊列并發(fā)送消息到隊列
?3///?</summary>
?4public?static?void?SendMessage()
?5{
?6????try
?7????{
?8????????//連接到本地的隊列
?9????????MessageQueue?myQueue?=?new?MessageQueue(".\\private$\\myQueue");
10????????
11????????Message?myMessage?=?new?Message();
12????????myMessage.Body?=?"消息內(nèi)容";
13????????myMessage.Formatter?=?new?XmlMessageFormatter(new?Type[]?{?typeof(string)?});
14????????//發(fā)送消息到隊列中
15????????myQueue.Send(myMessage);
16????}
17????catch?(ArgumentException?e)
18????{
19????????Console.WriteLine(e.Message);
20????}
21}
3、連接消息隊列并從消息隊列中接收消息
?2///?連接消息隊列并從隊列中接收消息
?3///?</summary>
?4public?static?void?ReceiveMessage()
?5{
?6????//連接到本地隊列
?7????MessageQueue?myQueue?=?new?MessageQueue(".\\private$\\myQueue");
?8????myQueue.Formatter?=?new?XmlMessageFormatter(new?Type[]?{?typeof(string)?});
?9????try
10????{
11????????//從隊列中接收消息
12????????Message?myMessage?=?myQueue.Receive();
13????????string?context?=?(string)myMessage.Body;?//獲取消息的內(nèi)容
14????????Console.WriteLine("消息內(nèi)容為:"?+?context);
15????}
16????catch?(MessageQueueException?e)
17????{
18????????Console.WriteLine(e.Message);
19????}
20????catch?(InvalidCastException?e)
21????{
22????????Console.WriteLine(e.Message);
23????}
24}
4、連接隊列并清空隊列的全部消息
2///?清空指定隊列的消息
3///?</summary>
4public?static?void?ClearMessage()
5{
6????MessageQueue?myQueue?=?new?MessageQueue(".\\private$\\myQueue");
7????myQueue.Purge();
8}
5、連接隊列并獲取隊列的全部消息
?2///?連接隊列并獲取隊列的全部消息
?3///?</summary>
?4public?static?void?GetAllMessage()
?5{
?6????//連接到本地隊列
?7????MessageQueue?myQueue?=?new?MessageQueue(".\\private$\\myQueue");
?8????Message[]?message?=?myQueue.GetAllMessages();
?9????XmlMessageFormatter?formatter?=?new?XmlMessageFormatter(new?Type[]?{?typeof(string)?});
10????for?(int?i?=?0;?i?<?message.Length;?i++)
11????{
12????????message[i].Formatter?=?formatter;
13????????Console.WriteLine(message[i].Body.ToString());
14????}
15}
???? 上面依次的列舉出來5個方法,這里我就不做測試了。上述方法全部通過測試的,我在后面提供個連接,沒弄清楚的朋友可下載源程序自己去運行調(diào)試下。
??1using?System;
??2using?System.Collections.Generic;
??3using?System.Text;
??4using?System.Messaging;
??5
??6namespace?MSMQ
??7{
??8????class?Program
??9????{
?10????????static?void?Main(string[]?args)
?11????????{
?12????????????Createqueue(".\\myQueue");
?13????????????SendMessage();
?14????????????GetAllMessage();
?15????????????//ReceiveMessage();
?16????????}
?17
?18
?19????????///?<summary>
?20????????///?通過Create方法創(chuàng)建使用指定路徑的新消息隊列
?21????????///?</summary>
?22????????///?<param?name="queuePath"></param>
?23????????public?static?void?Createqueue(string?queuePath)
?24????????{
?25????????????try
?26????????????{
?27????????????????if?(!MessageQueue.Exists(queuePath))
?28????????????????{
?29????????????????????MessageQueue.Create(@".\private$\myQueue");
?30????????????????}
?31????????????????else
?32????????????????{
?33????????????????????Console.WriteLine(queuePath?+?"已經(jīng)存在!");
?34????????????????}
?35????????????}
?36????????????catch?(MessageQueueException?e)
?37????????????{
?38????????????????Console.WriteLine(e.Message);
?39????????????}
?40????????}
?41
?42????????///?<summary>
?43????????///?連接消息隊列并發(fā)送消息到隊列
?44????????///?</summary>
?45????????public?static?void?SendMessage()
?46????????{
?47????????????try
?48????????????{
?49????????????????//連接到本地的隊列
?50????????????????MessageQueue?myQueue?=?new?MessageQueue(".\\private$\\myQueue");
?51????????????????
?52????????????????Message?myMessage?=?new?Message();
?53????????????????myMessage.Body?=?"消息內(nèi)容";
?54????????????????myMessage.Formatter?=?new?XmlMessageFormatter(new?Type[]?{?typeof(string)?});
?55????????????????//發(fā)送消息到隊列中
?56????????????????myQueue.Send(myMessage);
?57????????????}
?58????????????catch?(ArgumentException?e)
?59????????????{
?60????????????????Console.WriteLine(e.Message);
?61????????????}
?62????????}
?63
?64????????///?<summary>
?65????????///?連接消息隊列并從隊列中接收消息
?66????????///?</summary>
?67????????public?static?void?ReceiveMessage()
?68????????{
?69????????????//連接到本地隊列
?70????????????MessageQueue?myQueue?=?new?MessageQueue(".\\private$\\myQueue");
?71????????????myQueue.Formatter?=?new?XmlMessageFormatter(new?Type[]?{?typeof(string)?});
?72????????????try
?73????????????{
?74????????????????//從隊列中接收消息
?75????????????????Message?myMessage?=?myQueue.Receive();
?76????????????????string?context?=?(string)myMessage.Body;?//獲取消息的內(nèi)容
?77????????????????Console.WriteLine("消息內(nèi)容為:"?+?context);
?78????????????}
?79????????????catch?(MessageQueueException?e)
?80????????????{
?81????????????????Console.WriteLine(e.Message);
?82????????????}
?83????????????catch?(InvalidCastException?e)
?84????????????{
?85????????????????Console.WriteLine(e.Message);
?86????????????}
?87????????}
?88
?89????????///?<summary>
?90????????///?清空指定隊列的消息
?91????????///?</summary>
?92????????public?static?void?ClearMessage()
?93????????{
?94????????????MessageQueue?myQueue?=?new?MessageQueue(".\\private$\\myQueue");
?95????????????myQueue.Purge();
?96????????}
?97
?98????????///?<summary>
?99????????///?連接隊列并獲取隊列的全部消息
100????????///?</summary>
101????????public?static?void?GetAllMessage()
102????????{
103????????????//連接到本地隊列
104????????????MessageQueue?myQueue?=?new?MessageQueue(".\\private$\\myQueue");
105????????????Message[]?message?=?myQueue.GetAllMessages();
106????????????XmlMessageFormatter?formatter?=?new?XmlMessageFormatter(new?Type[]?{?typeof(string)?});
107????????????for?(int?i?=?0;?i?<?message.Length;?i++)
108????????????{
109????????????????message[i].Formatter?=?formatter;
110????????????????Console.WriteLine(message[i].Body.ToString());
111????????????}
112????????}
113????}
114}
115
六、復雜消息發(fā)送實例?????通過上面一系列的介紹,對于簡單消息的發(fā)送和接收及消息的管理應該都不會有什么問題了,下面我在介紹一下關(guān)于復雜的消息處理,現(xiàn)在有這樣一個需求,要求通過消息隊列將一本圖書信息發(fā)送到隊列里,然后從消息隊列里讀取出來。圖書的基本信息包括圖書編號、圖書名稱、圖書作者以及圖書定價,這樣的一個復雜的對象類型怎么來傳輸呢?詳細如下:
?1namespace?MSMQ.App
?2{
?3????public?class?Book
?4????{
?5????????private?int?_BookId;
?6????????public?int?BookId
?7????????{
?8????????????get?{?return?_BookId;?}
?9????????????set?{?_BookId?=?value;?}
10????????}
11
12????????private?string?_BookName;
13????????public?string?BookName
14????????{
15????????????get?{?return?_BookName;?}
16????????????set?{?_BookName?=?value;?}
17????????}
18
19????????private?string?_BookAuthor;
20????????public?string?BookAuthor
21????????{
22????????????get?{?return?_BookAuthor;?}
23????????????set?{?_BookAuthor?=?value;?}
24????????}
25
26????????private?double?_BookPrice;
27????????public?double?BookPrice
28????????{
29????????????get?{?return?_BookPrice;?}
30????????????set?{?_BookPrice?=?value;?}
31????????}
32????}
33} ?1namespace?MSMQ.App
?2{
?3????public?class?MsgQueue
?4????{
?5????????///?<summary>
?6????????///?通過Create方法創(chuàng)建使用指定路徑的新消息隊列
?7????????///?</summary>
?8????????///?<param?name="queuePath"></param>
?9????????public?static?void?Createqueue(string?queuePath)
10????????{
11????????????try
12????????????{
13????????????????if?(!MessageQueue.Exists(queuePath))
14????????????????{
15????????????????????MessageQueue.Create(@".\private$\myQueue");
16????????????????????MessageBox.Show("創(chuàng)建隊列成功!");
17????????????????}
18????????????????else
19????????????????{
20????????????????????MessageBox.Show(queuePath?+?"已經(jīng)存在!");
21????????????????}
22????????????}
23????????????catch?(MessageQueueException?e)
24????????????{
25????????????????MessageBox.Show(e.Message);
26????????????}
27????????}
28
29????????///?<summary>
30????????///?連接消息隊列并發(fā)送消息到隊列
31????????///?</summary>
32????????public?static?bool?SendMessage(Book?book)
33????????{
34????????????bool?flag?=?false;
35????????????try
36????????????{
37????????????????//連接到本地的隊列
38????????????????MessageQueue?myQueue?=?new?MessageQueue(".\\private$\\myQueue");
39
40????????????????System.Messaging.Message?myMessage?=?new?System.Messaging.Message();
41????????????????myMessage.Body?=?book;
42????????????????myMessage.Formatter?=?new?XmlMessageFormatter(new?Type[]?{?typeof(MSMQ.App.Book)?});
43????????????????//發(fā)送消息到隊列中
44????????????????myQueue.Send(myMessage);
45????????????????flag?=?true;
46????????????}
47????????????catch?(ArgumentException?e)
48????????????{
49????????????????MessageBox.Show(e.Message);
50????????????}
51????????????return?flag;
52????????}
53
54????????///?<summary>
55????????///?連接消息隊列并從隊列中接收消息
56????????///?</summary>
57????????public?static?string?ReceiveMessage()
58????????{
59????????????//連接到本地隊列
60????????????MessageQueue?myQueue?=?new?MessageQueue(".\\private$\\myQueue");
61????????????myQueue.Formatter?=?new?XmlMessageFormatter(new?Type[]?{?typeof(MSMQ.App.Book)?});
62????????????try
63????????????{
64????????????????//從隊列中接收消息
65????????????????System.Messaging.Message?myMessage?=?myQueue.Receive();
66????????????????Book?book?=?(Book)myMessage.Body;?//獲取消息的內(nèi)容
67????????????????return?string.Format("編號:{0},書名:{1},作者:{2},定價:{3}",
68????????????????????book.BookId,
69????????????????????book.BookName,
70????????????????????book.BookAuthor,
71????????????????????book.BookPrice);
72????????????}
73????????????catch?(MessageQueueException?e)
74????????????{
75????????????????MessageBox.Show(e.Message);
76????????????}
77????????????catch?(InvalidCastException?e)
78????????????{
79????????????????MessageBox.Show(e.Message);
80????????????}
81????????????return?null;
82????????}
83????}
84}
???? 其實發(fā)送復雜的消息也就是在消息序列化上有些差別,別的地方與發(fā)送普通文本消息沒什么大的變化,上面類里提供了創(chuàng)建隊列,發(fā)送消息到隊列,從隊列獲取消息三個方法,測試結(jié)果如下:
???? 上示例中,完成了一個復雜類型的消息發(fā)送到隊列及從隊列中讀取的演義,詳細請下載代碼查看:??點擊這里下載本文示例代碼???? 本文就簡單介紹于此,更深入的學習MSMQ請查閱相關(guān)資料(如PetShop4里的定單處理策略)。
總結(jié)
以上是生活随笔為你收集整理的ASP.NET中进行消息处理(MSMQ) 一的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 日志插件 log4net 的使用
- 下一篇: 几点汽车常见故障判断和自查!