Anvisningar: Anropa WCF-tjänståtgärder asynkront
Den här artikeln beskriver hur en klient kan komma åt en tjänståtgärd asynkront. Tjänsten i den här artikeln implementerar ICalculator
gränssnittet. Klienten kan anropa åtgärderna i det här gränssnittet asynkront med hjälp av den händelsedrivna asynkrona samtalsmodellen. (Mer information om den händelsebaserade asynkrona samtalsmodellen finns i Flertrådad programmering med det händelsebaserade asynkrona mönstret). Ett exempel som visar hur du implementerar en åtgärd asynkront i en tjänst finns i Så här implementerar du en asynkron tjänståtgärd. Mer information om synkrona och asynkrona åtgärder finns i Synkrona och Asynkrona åtgärder.
Kommentar
Den händelsedrivna asynkrona samtalsmodellen stöds inte när du använder en ChannelFactory<TChannel>. Information om hur du gör asynkrona anrop med hjälp av finns ChannelFactory<TChannel>i Så här anropar du åtgärder asynkront med hjälp av en kanalfabrik.
Procedur
Anropa WCF-tjänståtgärder asynkront
Kör verktyget ServiceModel Metadata Utility Tool (Svcutil.exe) med både kommandoalternativen
/async
/tcv:Version35
och tillsammans enligt följande kommando.svcutil /n:http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples http://localhost:8000/servicemodelsamples/service/mex /a /tcv:Version35
Detta genererar, utöver de synkrona och standarddelegeringsbaserade asynkrona åtgärderna, en WCF-klientklass som innehåller:
Två
<operationName>``Async
åtgärder för användning med den händelsebaserade asynkrona anropande metoden. Till exempel:public void AddAsync(double n1, double n2) { this.AddAsync(n1, n2, null); } public void AddAsync(double n1, double n2, object userState) { if ((this.onBeginAddDelegate == null)) { this.onBeginAddDelegate = new BeginOperationDelegate(this.OnBeginAdd); } if ((this.onEndAddDelegate == null)) { this.onEndAddDelegate = new EndOperationDelegate(this.OnEndAdd); } if ((this.onAddCompletedDelegate == null)) { this.onAddCompletedDelegate = new System.Threading.SendOrPostCallback(this.OnAddCompleted); } base.InvokeAsync(this.onBeginAddDelegate, new object[] { n1, n2}, this.onEndAddDelegate, this.onAddCompletedDelegate, userState); }
Public Overloads Sub AddAsync(ByVal n1 As Double, ByVal n2 As Double) Me.AddAsync(n1, n2, Nothing) End Sub Public Overloads Sub AddAsync(ByVal n1 As Double, ByVal n2 As Double, ByVal userState As Object) If (Me.onBeginAddDelegate Is Nothing) Then Me.onBeginAddDelegate = AddressOf Me.OnBeginAdd End If If (Me.onEndAddDelegate Is Nothing) Then Me.onEndAddDelegate = AddressOf Me.OnEndAdd End If If (Me.onAddCompletedDelegate Is Nothing) Then Me.onAddCompletedDelegate = AddressOf Me.OnAddCompleted End If MyBase.InvokeAsync(Me.onBeginAddDelegate, New Object() {n1, n2}, Me.onEndAddDelegate, Me.onAddCompletedDelegate, userState) End Sub
Åtgärden slutförde händelser i formuläret
<operationName>``Completed
för användning med den händelsebaserade asynkrona anropande metoden. Till exempel:public event System.EventHandler<AddCompletedEventArgs> AddCompleted;
Public Event AddCompleted As System.EventHandler(Of AddCompletedEventArgs)
System.EventArgs typer för varje åtgärd (i formuläret
<operationName>``CompletedEventArgs
) för användning med den händelsebaserade asynkrona anropande metoden. Till exempel:[System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public partial class AddCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { private object[] results; public AddCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : base(exception, cancelled, userState) { this.results = results; } public double Result { get { base.RaiseExceptionIfNecessary(); return ((double)(this.results[0])); } } }
<System.Diagnostics.DebuggerStepThroughAttribute(), _ System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")> _ Partial Public Class AddCompletedEventArgs Inherits System.ComponentModel.AsyncCompletedEventArgs Private results() As Object Public Sub New(ByVal results() As Object, ByVal exception As System.Exception, ByVal cancelled As Boolean, ByVal userState As Object) MyBase.New(exception, cancelled, userState) Me.results = results End Sub Public ReadOnly Property Result() As Double Get MyBase.RaiseExceptionIfNecessary Return CType(Me.results(0),Double) End Get End Property End Class
I det anropande programmet skapar du en motringningsmetod som ska anropas när den asynkrona åtgärden är klar, enligt följande exempelkod.
// Asynchronous callbacks for displaying results. static void AddCallback(object sender, AddCompletedEventArgs e) { Console.WriteLine("Add Result: {0}", e.Result); }
' Asynchronous callbacks for displaying results. Private Shared Sub AddCallback(ByVal sender As Object, ByVal e As AddCompletedEventArgs) Console.WriteLine("Add Result: {0}", e.Result) End Sub
Innan du anropar åtgärden använder du en ny generisk System.EventHandler<TEventArgs> typ
<operationName>``EventArgs
för att lägga till hanteringsmetoden (som skapades i föregående steg) till<operationName>``Completed
händelsen. Anropa<operationName>``Async
sedan metoden. Till exempel:// AddAsync double value1 = 100.00D; double value2 = 15.99D; client.AddCompleted += new EventHandler<AddCompletedEventArgs>(AddCallback); client.AddAsync(value1, value2); Console.WriteLine("Add({0},{1})", value1, value2);
' AddAsync Dim value1 As Double = 100 Dim value2 As Double = 15.99 AddHandler client.AddCompleted, AddressOf AddCallback client.AddAsync(value1, value2) Console.WriteLine("Add({0},{1})", value1, value2)
Exempel
Kommentar
Designriktlinjerna för det händelsebaserade asynkrona modelltillståndet att om mer än ett värde returneras returneras ett värde som Result
egenskapen och de andra returneras som egenskaper för EventArgs objektet. Ett resultat av detta är att om en klient importerar metadata med hjälp av de händelsebaserade asynkrona kommandoalternativen och åtgärden returnerar mer än ett värde, returnerar standardobjektet EventArgs ett värde som Result
egenskapen och resten är egenskaperna för EventArgs objektet. Om du vill ta emot meddelandeobjektet som Result
egenskap och ha de returnerade värdena som egenskaper för objektet använder du kommandoalternativet /messageContract
. Detta genererar en signatur som returnerar svarsmeddelandet som Result
egenskapen på EventArgs objektet. Alla interna returvärden är sedan egenskaper för svarsmeddelandeobjektet.
using System;
namespace Microsoft.ServiceModel.Samples
{
// The service contract is defined in generatedClient.cs, generated from the service by the svcutil tool.
class Client
{
static void Main()
{
Console.WriteLine("Press <ENTER> to terminate client once the output is displayed.");
Console.WriteLine();
// Create a client
CalculatorClient client = new CalculatorClient();
// AddAsync
double value1 = 100.00D;
double value2 = 15.99D;
client.AddCompleted += new EventHandler<AddCompletedEventArgs>(AddCallback);
client.AddAsync(value1, value2);
Console.WriteLine("Add({0},{1})", value1, value2);
// SubtractAsync
value1 = 145.00D;
value2 = 76.54D;
client.SubtractCompleted += new EventHandler<SubtractCompletedEventArgs>(SubtractCallback);
client.SubtractAsync(value1, value2);
Console.WriteLine("Subtract({0},{1})", value1, value2);
// Multiply
value1 = 9.00D;
value2 = 81.25D;
double result = client.Multiply(value1, value2);
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);
// Divide
value1 = 22.00D;
value2 = 7.00D;
result = client.Divide(value1, value2);
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
Console.ReadLine();
//Closing the client gracefully closes the connection and cleans up resources
client.Close();
}
// Asynchronous callbacks for displaying results.
static void AddCallback(object sender, AddCompletedEventArgs e)
{
Console.WriteLine("Add Result: {0}", e.Result);
}
static void SubtractCallback(object sender, SubtractCompletedEventArgs e)
{
Console.WriteLine("Subtract Result: {0}", e.Result);
}
}
}
Namespace Microsoft.ServiceModel.Samples
' The service contract is defined in generatedClient.vb, generated from the service by the svcutil tool.
Class Client
Public Shared Sub Main()
Console.WriteLine("Press <ENTER> to terminate client once the output is displayed.")
Console.WriteLine()
' Create a client
Dim client As New CalculatorClient()
' AddAsync
Dim value1 As Double = 100
Dim value2 As Double = 15.99
AddHandler client.AddCompleted, AddressOf AddCallback
client.AddAsync(value1, value2)
Console.WriteLine("Add({0},{1})", value1, value2)
' SubtractAsync
value1 = 145
value2 = 76.54
AddHandler client.SubtractCompleted, AddressOf SubtractCallback
client.SubtractAsync(value1, value2)
Console.WriteLine("Subtract({0},{1})", value1, value2)
' Multiply
value1 = 9
value2 = 81.25
Dim result As Double = client.Multiply(value1, value2)
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result)
' Divide
value1 = 22
value2 = 7
result = client.Divide(value1, value2)
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result)
Console.ReadLine()
'Closing the client gracefully closes the connection and cleans up resources
client.Close()
End Sub
' Asynchronous callbacks for displaying results.
Private Shared Sub AddCallback(ByVal sender As Object, ByVal e As AddCompletedEventArgs)
Console.WriteLine("Add Result: {0}", e.Result)
End Sub
Private Shared Sub SubtractCallback(ByVal sender As Object, ByVal e As SubtractCompletedEventArgs)
Console.WriteLine("Subtract Result: {0}", e.Result)
End Sub
End Class
End Namespace