HOW TO:以非同步方式接收訊息
更新:2007 年 11 月
您可用來非同步擷取訊息的方式有二:使用事件處理常式來在作業完成處理時接收告知,或是使用回呼。如需非同步訊息的概觀,請參閱非同步訊息處理。
在事件告知中,您必須先將事件處理常式繫結至要在非同步呼叫完成時執行的程序。接著可在程式碼中呼叫 BeginReceive 方法。這會在可取得訊息時或在逾時參數到期時啟動非同步處理並將處理傳回至您的元件。當呼叫傳回時,系統會執行您所定義的委派並處理擷取的結果。接著呼叫 EndReceive 方法來指出作業結束。
![]() |
---|
BeginReceive 將只擷取單一訊息。如果您要繼續非同步處理多個訊息,則必須再次呼叫 BeginReceive 方法,或使用 BeginReceive 上的回呼參數來呼叫委派,以繼續監看到達佇列的新訊息。 |
除了非同步接收訊息之外,您也可非同步窺視訊息。兩個程序的模式相當類似,唯一不同的是您必須使用 BeginPeek 方法來進行非同步窺視。
若要以程式設計的方式建立 MessageQueue 物件
將 System.Messaging.dll 的參考加入至專案。
在實作的類別中建立 MessageQueue 物件的執行個體,並設定其 Path 屬性 (在建構函式中) 和 Formatter 屬性。
' Add this to the constructor Dim targetTypeNames() As String = _ New String() {"System.String,mscorlib"} mq.Formatter = _ New System.Messaging.XmlMessageFormatter(targetTypeNames)
// Add this to the class declarations. System.Messaging.MessageQueue mq = new System.Messaging.MessageQueue(".\\MyQueue"); // Add this to the constructor. mq.Formatter = new System.Messaging.XmlMessageFormatter( new string[] { "System.String,mscorlib" });
若要在設計工具中建立 MessageQueue 物件
將 System.Messaging.dll 的參考加入至專案。
從 [工具箱] 將 MessageQueue 元件拖曳到設計工具中。將 QueueName 屬性設定為 mq。將 Formatter 屬性設定為 XmlMessageFormatter。將 Path 屬性設定為 ".\MyQueue"。
若要使用事件告知來非同步接收訊息
為 ReceiveCompleted 事件建立事件處理常式。在設計工具中,按兩下 MessageQueue 元件,然後加入下面所示的程式碼。
Private Sub mq_ReceiveCompleted(ByVal sender As System.Object, _ ByVal e As System.Messaging.ReceiveCompletedEventArgs) _ Handles mq.ReceiveCompleted ' Add code here to respond to message. End Sub
private void mq_ReceiveCompleted(object sender, System.Messaging.ReceiveCompletedEventArgs e) { // Add code here to respond to message. }
在事件處理常式內寫入擷取訊息的程式碼,使用 Message 物件來擷取非同步呼叫的結果。下列程式碼會擷取訊息,並將訊息顯示在主控台。
Private Sub mq_ReceiveCompleted(ByVal sender As System.Object, _ ByVal e As System.Messaging.ReceiveCompletedEventArgs) _ Handles mq.ReceiveCompleted Dim m As System.Messaging.Message = mq.EndReceive(e.AsyncResult) m.Formatter = New System.Messaging.XmlMessageFormatter( _ New String() {"System.String,mscorlib"}) Console.WriteLine("Message: " + m.Body.ToString()) End Sub
private void mq_ReceiveCompleted(object sender, System.Messaging.ReceiveCompletedEventArgs e) { System.Messaging.Message m = mq.EndReceive(e.AsyncResult); m.Formatter = new System.Messaging.XmlMessageFormatter( new string[] { "System.String,mscorlib" }); Console.WriteLine("Message: " + (string)m.Body); }
在程式碼中的任一處呼叫 BeginReceive 方法來啟動非同步作業。例如,下列程式碼會在使用者按一下按鈕時呼叫方法。
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click mq.BeginReceive() End Sub
private void button1_Click(object sender, System.EventArgs e) { mq.BeginReceive(); }
如果想要繼續非同步接收訊息,請在 ReceiveCompleted 事件處理常式中再次呼叫 BeginReceive 方法,如下所示。這會讓您的元件繼續處理佇列上所接收的新訊息。
Private Sub mq_ReceiveCompleted(ByVal sender As System.Object, _ ByVal e As System.Messaging.ReceiveCompletedEventArgs) _ Handles mq.ReceiveCompleted Dim m As System.Messaging.Message = mq.EndReceive(e.AsyncResult) m.Formatter = New System.Messaging.XmlMessageFormatter( _ New String() {"System.String,mscorlib"}) Console.WriteLine("Message: " + m.Body.ToString()) mq.BeginReceive() End Sub
private void mq_ReceiveCompleted(object sender, System.Messaging.ReceiveCompletedEventArgs e) { System.Messaging.Message m = mq.EndReceive(e.AsyncResult); m.Formatter = new System.Messaging.XmlMessageFormatter( new string[] { "System.String,mscorlib" }); Console.WriteLine("Message: " + (string)m.Body); mq.BeginReceive(); }
若要使用回呼非同步接收訊息
建立定義訊息工作相關資訊的類別。在本案例中,定義 Customer 類別。
Public Class Customer Public Name As String = "" Public Sub New(ByVal newName As String) Name = newName End Sub End Class
public class Customer { public string Name = ""; public Customer(string name) { Name = name; } }
建立類別的執行個體這個物件會傳遞到回呼方法。
Dim george As New Customer("George")
Customer george = new Customer("George");
根據 AsyncCallback 委派建立回呼方法。這個方法將包含訊息接收後要完成的處理。result 參數的 AsyncState 屬性將包含您建立來傳遞訊息工作相關資訊的物件。在此情況下,AsyncState 是 Customer 物件。
Private Sub ReceiveCallback(ByVal result As System.IAsyncResult) Dim buyer As Customer = CType(result.AsyncState, Customer) Dim buyerName As String = buyer.Name End Sub
private void ReceiveCallback(System.IAsyncResult result) { Customer buyer = (Customer)result.AsyncState; string buyerName = buyer.Name; }
在程式碼中的任一處呼叫 BeginReceive 方法,來啟動非同步作業。例如,下列程式碼會在使用者按一下按鈕時呼叫方法。訊息會傳送到訊息佇列,然後從佇列讀取。上述步驟 3 中所定義的 ReceiveCallback 方法,會在接收訊息時呼叫。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles Button1.Click MessageQueue1.Send("Buy six eggs.", george.Name) MessageQueue1.BeginReceive(New System.TimeSpan(0, 0, 5), george, _ AddressOf ReceiveCallback) End Sub
private void button1_Click(object sender, System.EventArgs e) { messageQueue1.Send("Buy six eggs.", george.Name); messageQueue1.BeginReceive(new System.TimeSpan(0, 0, 5), george, new System.AsyncCallback(this.ReceiveCallback)); }