如何:异步接收消息
更新: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)); }