新聞

.NET中的消息隊列

發布時間

2018-05-26

來源

來自互聯網

移動

手機閱覽

為何使用消息隊列

您可能認為您能夠通過一個簡單的數據庫表(一個應用程序往其中寫入數據,另一個應用程序從中讀取數據)來應用消息隊列。消息隊列平臺更為穩定,因為它們通常擁有自己的安全機制、事務支持及其它功能。傳輸消息的路由功能是它的一個關鍵應用。MSMQ提供各種消息隊列平臺。

MSMQ簡介

MSMQ是Windows 2000、Windows XP、Windows Server 2003的一個組件,并將繼續包含在Windows Vista和以后的Windows服務器中。即使目標接收應用程序沒有運行,或運行發送或接收應用程序的計算機沒有聯網,協同合作的應用程序仍能利用MSMQ在彼此之間發送和接收消息。在到達目標隊列之前,消息由MSMQ存儲并轉發。接收應用程序能夠從隊列中恢復數據。

MSMQ之類消息隊列的主要特點在于它分離發送和接收應用程序,使其不必同時運行。這意味著一個應用程序能夠把數據存放在隊列中,而不用理會隊列中的項目是否被傳送到接收應用程序。

MSMQ是Windows的一個可選組件,只需通過Windows控制面板的添加或刪除Windows組件向導就可進行安裝。MSMQ有兩種配置模式:域模式或工作組模式(只使用私有隊列)。MSMQ安裝完成后,立即就可以在.NET應用程序中運行。

MSMQ交互

開發基于消息的應用程序從隊列開始。MSMQ包含四種隊列類型:

  • 外發隊列:消息發送到目的地之前,用它來臨時存儲消息。
  • 公共隊列:在主動目錄中公布。整個網絡各種服務器上的應用程序能夠通過主動目錄找到并應用公共隊列。
  • 私有隊列:這些是本地服務器上的隊列,對其它服務器無效(因此這些隊列不在主動目錄中公布。)
  • 系統隊列:包含日記隊列(由系統生成)、死隊列和事務型死信隊列。死消息無法傳送。

System.Messaging命名空間執行MSMQ的編程操作。這個命名空間有兩個主要的對象:

  • Message:隊列發送或讀取的實際消息或數據。
  • MessageQueue:接收/發送消息的MSMQ消息隊列。
  • MSMQ編程

    建立一個隊列是應用MSMQ的第一步。您可以通過Windows計算機管理控制臺中的消息隊列選項完成這一操作,或者自己編程建立一個隊列。列表A中的C#代碼建立了一個新的私有MSMQ消息隊列(如果不存在隊列),并同時創建一條消息。

    代碼應用MessageQueue類的Exists方法來確定是否存在一個名為TechRepublic的私有隊列。如存在,它用現有隊列示例這個MessageQueue對象;否則,就建立一個新隊列。

    新的Message對象用來向隊列發送一條消息。它的Label屬性指定在MSMQ控制臺中顯示的消息標題,其主體包含存放在隊列上的項目內容。在這種情況下,我只發送文本,但您能夠使用任何類型的對象。MessageQueue類的Send方法向隊列發送消息。列表B中是對應的VB.NET代碼。

    下一步即從隊列中讀取消息。這是一個簡單的過程,應用MessageQueue類的Receive方法即可。如果隊列中存在消息,Receive方法就返回一個消息對象;否則,它等待一條消息出現(您可以設置一個時間期限)。從隊列中恢復對象需要預先知道它的類型。

    MessageQueue類的Formatter屬性允許您輕松指定被恢復對象的類型。下面的簡單例子僅使用文本,所以它應用System.String。在列表C中,C#代碼從測試隊列中讀取消息。

    提交給Receive方法的TimeSpan對象指定異常出現時系統的等待時間。接下來設置這個例子中的Formatter方法,對象被轉換成字符串讀取前面存儲的文本。Receive方法從隊列中讀取消息,它的值顯示在控制臺中。在try塊的最后部分,隊列關閉。

    輕松應用消息

    MSMQ組合Windows和.NET的System.Messaging命名空間,使您可以方便地在.NET應用程序中利用消息。消息提供一種在企業應用程序中異步發送并接收消息(數據)的強大工具。

以下試文章來源
http://hi.baidu.com/sanlng/blog/item/5fc5bb510d4faa2043a75b28.html

三、發送信息

1、發送簡單消息

在消息發送前,首先要實例化MessageQueue的一個實例并指定其所對應的隊列。如下代碼

//實例化MessageQueue,并指向現有的一個名稱為VideoQueue隊列
MessageQueue MQ = new MessageQueue(@".\private$\VideoQueue");
MQ.Send("消息測試","測試消息");

(代碼片斷1)


2、發送復雜消息

VideoPath是將要被當作消息的Boby來進行傳遞的類型,其定義如下:
using System;
namespace Message.Bussiness
{
[Serializable]
public class VideoPath
{
string _sourceFilePath = string.Empty;
string _targetFilePath = string.Empty;

public VideoPath()
{
}

public VideoPath(string sourceFilePath,string targetFilePath)
{
this._sourceFilePath = sourceFilePath;
this._targetFilePath = targetFilePath;
}

public string SourceFilePath
{
get
{
return this._sourceFilePath;
}
set
{
this._sourceFilePath= value;
}
}

public string TargetFilePath
{
get
{
return this._targetFilePath;
}
set
{
this._targetFilePath = value;
}
}
}
}

(代碼片斷2)

       對該類的要求是,該類必須要有一個默認無參的公共構造函數,所有屬性必須是可讀寫的,且該類必須可以被序列化。利用Message將消息發送到隊列中。

MessageQueue MQ = new MessageQueue(@".\private$\VideoQueue");
VideoPath VPath = new VideoPath(Path.Combine(Server.MapPath("."),"Video\\output.wmv"),Path.Combine(Server.MapPath("."),"Flv\\output.flv"));
System.Messaging.Message message = new System.Messaging.Message();
message.Label = "視頻轉換所用消息";
message.Body = VPath;
MQ.Send(message);

(代碼片斷3)

四、接收消息

1、接收簡單類型的消息

2、接收復雜類型的消息
對于“代碼片斷3”所示的消息,在接收時可按如下方法:
MessageQueue MQ = new MessageQueue(@".\private$\VideoQueue");
//調用MessageQueue的Receive方法接收消息
System.Messaging.Message message = MQ.Receive( TimeSpan.FromSeconds(5));
if ( message != null )
{
message.Formatter = new System.Messaging.XmlMessageFormatter(new string[]{"Message.Bussiness.VideoPath,Message"});
VideoPath Vpath = (VideoPath)message.Body;
Response.Write(Vpath.SourceFilePath);
}
else
{
Response.Write("沒有找到消息!");
}

需要注意的是,如果消息是一個自定義類型對象時,必須指定Message的序列化器,即Formatter屬性。不合適的Formatter是無法正確反序列化消息的。

資訊列表

其他的資訊
OTHER