Procedura: ricevere messaggi in modo asincrono
Aggiornamento: novembre 2007
È possibile recuperare i messaggi in modalità asincrona in due modi: utilizzando un gestore eventi per ricevere la notifica al termine dell'elaborazione dell'operazione o utilizzando un callback. Per una panoramica della messaggistica asincrona, vedere Elaborazione asincrona dei messaggi.
Nella notifica degli eventi si esegue in primo luogo l'associazione di un gestore eventi alla routine che si desidera eseguire al termine della chiamata asincrona, quindi si chiama il metodo BeginReceive nel codice, avviando così l'elaborazione asincrona e restituendo l'elaborazione al componente quando un messaggio diventa disponibile o quando il parametro di timeout scade. Quando la chiamata viene restituita, nel sistema viene eseguito il delegato definito e viene elaborato il messaggio recuperato. È a questo punto possibile chiamare il metodo EndReceive per indicare la fine dell'operazione.
Nota: |
---|
Il metodo BeginReceive consente di recuperare un solo messaggio. Se si desidera continuare l'elaborazione asincrona dei messaggi, sarà necessario chiamare di nuovo il metodo BeginReceive o utilizzare il parametro di callback di BeginReceive per chiamare un delegato che continuerà a controllare l'arrivo di nuovi messaggi nella coda. |
Oltre a ricevere, è possibile anche visualizzare i messaggi in modalità asincrona. Il modello per entrambi i processi è molto simile, con la differenza che per la visualizzazione asincrona si utilizza il metodo BeginPeek.
Per creare l'oggetto MessageQueue a livello di codice
Aggiungere al progetto un riferimento a System.Messaging.dll.
Creare un'istanza dell'oggetto MessageQueue nella classe che si sta implementando e impostarne le proprietà Path (nel costruttore) e 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" });
Per creare l'oggetto MessageQueue nella finestra di progettazione
Aggiungere al progetto un riferimento a System.Messaging.dll.
Dalla Casella degli strumenti trascinare un componente MessageQueue nella finestra di progettazione. Impostare la proprietà QueueName su mq. Impostare la proprietà Formatter su XmlMessageFormatter. Impostare la proprietà Path su ".\MyQueue".
Per ricevere un messaggio in modalità asincrona mediante la notifica dell'evento
Creare un gestore eventi per l'evento ReceiveCompleted. Nella finestra di progettazione fare doppio clic sul componente MessageQueue e aggiungere il codice riportato di seguito.
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. }
Scrivere il codice all'interno del gestore eventi per recuperare il messaggio, utilizzando l'oggetto Message per il recupero dei risultati della chiamata asincrona. Nel codice che segue, il messaggio viene recuperato e visualizzato nella console.
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); }
Chiamare il metodo BeginReceive in un punto qualsiasi del codice per avviare l'operazione asincrona. Nel codice che segue, ad esempio, il metodo viene chiamato quando l'utente fa clic su un pulsante.
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(); }
Se si desidera continuare a ricevere messaggi in modo asincrono, chiamare di nuovo il metodo BeginReceive nel gestore eventi ReceiveCompleted, come indicato di seguito. In tal modo, sul componente continuerà l'elaborazione dei nuovi messaggi quando vengono ricevuti nella coda.
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(); }
Per ricevere un messaggio in modalità asincrona utilizzando un callback
Creare una classe che definisca le informazioni di rilievo per l'attività del messaggio. In questo caso, definire una classe 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; } }
Creare un'istanza della classe. Questo oggetto verrà passato al metodo di callback.
Dim george As New Customer("George")
Customer george = new Customer("George");
Creare un metodo di callback in base al delegato AsyncCallback. Questo metodo conterrà il codice per le operazioni da svolgere dopo la ricezione del messaggio. La proprietà AsyncState del parametro result conterrà l'oggetto creato per passare informazioni sull'attività del messaggio. In questo caso, AsyncState è un oggetto 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; }
Chiamare il metodo BeginReceive in un punto qualsiasi del codice per avviare l'operazione asincrona. Nel codice che segue, ad esempio, il metodo viene chiamato quando l'utente fa clic su un pulsante. Un messaggio viene inviato alla coda messaggi e quindi letto dalla coda. Il metodo ReceiveCallback, definito nel passaggio 3 precedente, viene chiamato alla ricezione del messaggio.
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)); }
Vedere anche
Attività
Procedura: visualizzare i messaggi
Procedura: ricevere messaggi a livello di codice
Procedura: creare istanze del componente MessageQueue
Concetti
Elaborazione asincrona dei messaggi