Anvisningar: Anropa åtgärder asynkront med hjälp av en kanalfabrik
Det här avsnittet beskriver hur en klient kan komma åt en tjänståtgärd asynkront när du använder ett ChannelFactory<TChannel>-baserat klientprogram. (När du använder ett System.ServiceModel.ClientBase<TChannel> objekt för att anropa en tjänst kan du använda den händelsedrivna asynkrona samtalsmodellen. Mer information finns i Så här anropar du tjänståtgärder asynkront. Mer information om den händelsebaserade asynkrona samtalsmodellen finns i Händelsebaserat Asynkront mönster (EAP).)
Tjänsten i det här avsnittet implementerar ICalculator
gränssnittet. Klienten kan anropa åtgärderna i det här gränssnittet asynkront, vilket innebär att åtgärder som Add
är uppdelade i två metoder, BeginAdd
och EndAdd
, vars tidigare initierar anropet och det senare hämtar resultatet när åtgärden slutförs. 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.
Procedur
Anropa WCF-tjänståtgärder asynkront
Kör verktyget ServiceModel Metadata Utility Tool (Svcutil.exe) med alternativet
/async
som du ser i följande kommando.svcutil /n:http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples http://localhost:8000/servicemodelsamples/service/mex /a
Detta genererar en asynkron klientversion av tjänstkontraktet för åtgärden.
Skapa en motringningsfunktion som ska anropas när den asynkrona åtgärden är klar, som du ser i följande exempelkod.
static void AddCallback(IAsyncResult ar) { double result = ((CalculatorClient)ar.AsyncState).EndAdd(ar); Console.WriteLine("Add Result: {0}", result); }
Private Shared Sub AddCallback(ByVal ar As IAsyncResult) Dim result = (CType(ar.AsyncState, CalculatorClient)).EndAdd(ar) Console.WriteLine("Add Result: {0}", result) End Sub
Om du vill komma åt en tjänståtgärd asynkront skapar du klienten och anropar
Begin[Operation]
(till exempelBeginAdd
) och anger en återanropsfunktion, som du ser i följande exempelkod.ChannelFactory<ICalculatorChannel> factory = new ChannelFactory<ICalculatorChannel>(); ICalculatorChannel channelClient = factory.CreateChannel(); // BeginAdd double value1 = 100.00D; double value2 = 15.99D; IAsyncResult arAdd = channelClient.BeginAdd(value1, value2, AddCallback, channelClient); Console.WriteLine("Add({0},{1})", value1, value2);
Dim factory As New ChannelFactory(Of ICalculatorChannel)() Dim channelClient As ICalculatorChannel = factory.CreateChannel() ' BeginAdd Dim value1 = 100.0R Dim value2 = 15.99R Dim arAdd As IAsyncResult = channelClient.BeginAdd(value1, value2, AddressOf AddCallback, channelClient) Console.WriteLine("Add({0},{1})", value1, value2)
När återanropsfunktionen körs anropar
End<operation>
klienten (till exempelEndAdd
) för att hämta resultatet.
Exempel
Tjänsten som används med klientkoden som används i föregående procedur implementerar ICalculator
gränssnittet enligt följande kod. På tjänstsidan Add
anropas kontraktets åtgärder och Subtract
synkront av WCF-körningstiden (Windows Communication Foundation), även om föregående klientsteg anropas asynkront på klienten. Åtgärderna Multiply
och Divide
används för att anropa tjänsten asynkront på tjänstsidan, även om klienten anropar dem synkront. I det här exemplet anges egenskapen AsyncPattern till true
. Den här egenskapsinställningen, i kombination med implementeringen av det asynkrona .NET Framework-mönstret, instruerar körningen att anropa åtgärden asynkront.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
//Multiply involves some file I/O so we'll make it Async.
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginMultiply(double n1, double n2, AsyncCallback callback, object state);
double EndMultiply(IAsyncResult ar);
//Divide involves some file I/O so we'll make it Async.
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginDivide(double n1, double n2, AsyncCallback callback, object state);
double EndDivide(IAsyncResult ar);
}
<ServiceContract(Namespace:="http://Microsoft.ServiceModel.Samples")> _
Public Interface ICalculator
<OperationContract> _
Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract> _
Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double
'Multiply involves some file I/O so we'll make it Async.
<OperationContract(AsyncPattern:=True)> _
Function BeginMultiply(ByVal n1 As Double, ByVal n2 As Double, ByVal callback As AsyncCallback, ByVal state As Object) As IAsyncResult
Function EndMultiply(ByVal ar As IAsyncResult) As Double
'Divide involves some file I/O so we'll make it Async.
<OperationContract(AsyncPattern:=True)> _
Function BeginDivide(ByVal n1 As Double, ByVal n2 As Double, ByVal callback As AsyncCallback, ByVal state As Object) As IAsyncResult
Function EndDivide(ByVal ar As IAsyncResult) As Double
End Interface