方法 : メッセージを非同期で取得する
更新 : 2007 年 11 月
メッセージを非同期で取得するには、2 つの方法があります。イベント ハンドラを使用して操作の完了時に通知を受け取る方法と、コールバックを使用する方法です。非同期メッセージングの概要については、「非同期のメッセージ処理」を参照してください。
イベント通知では、まず、非同期呼び出しの完了時に実行するプロシージャにイベント ハンドラをバインドします。その後、コードで BeginReceive メソッドを呼び出します。これにより、非同期処理が開始され、メッセージが到着するか、またはタイムアウト期限が切れたときに、コンポーネントに処理が渡されます。呼び出しが完了すると、システムは定義されたデリゲートを実行し、取得の結果を処理します。その後で、EndReceive メソッドを呼び出して操作の終了を指示します。
メモ : |
---|
BeginReceive は 1 つのメッセージだけを取得します。引き続きメッセージを非同期で処理する場合は、もう一度 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)); }
参照
処理手順
方法 : MessageQueue コンポーネントのインスタンスを作成する