Sdílet prostřednictvím


Postupy: Asynchronní volání operací pomocí objektu pro vytváření kanálů

Toto téma popisuje, jak může klient přistupovat k operaci služby asynchronně při použití ChannelFactory<TChannel>klientské aplikace založené na. (Při použití objektu System.ServiceModel.ClientBase<TChannel> k vyvolání služby můžete použít model asynchronního volání řízeného událostmi. Další informace naleznete v tématu Postupy: Asynchronní volání operací služby. Další informace o asynchronním volajícím modelu založeném na událostech najdete v tématu Asynchronní vzor založený na událostech (EAP).)

Služba v tomto tématu implementuje ICalculator rozhraní. Klient může volat operace v tomto rozhraní asynchronně, což znamená, že operace Add jako jsou rozdělené do dvou metod, BeginAdd a EndAdd, první z nich zahájí volání a druhý z nich načte výsledek po dokončení operace. Příklad znázorňující, jak implementovat operaci asynchronně ve službě, naleznete v tématu Postupy: Implementace asynchronní operace služby. Podrobnosti o synchronních a asynchronníchoperacích

Postup

Asynchronní volání operací služby WCF

  1. Spusťte nástroj ServiceModel Metadata Utility Tool (Svcutil.exe) s /async možností, jak je znázorněno v následujícím příkazu.

    svcutil /n:http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples http://localhost:8000/servicemodelsamples/service/mex /a
    

    Tím se vygeneruje asynchronní verze klienta kontraktu služby pro operaci.

  2. Vytvořte funkci zpětného volání, která se má volat při dokončení asynchronní operace, jak je znázorněno v následujícím ukázkovém kódu.

    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
    
  3. Pokud chcete k operaci služby přistupovat asynchronně, vytvořte klienta a volejte Begin[Operation] (například BeginAdd) a zadejte funkci zpětného volání, jak je znázorněno v následujícím vzorovém kódu.

    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)
    

    Když se funkce zpětného volání spustí, klient zavolá End<operation> (například EndAdd) k načtení výsledku.

Příklad

Služba, která se používá s klientským kódem použitým v předchozím postupu, implementuje ICalculator rozhraní, jak je znázorněno v následujícím kódu. Na straně AddSubtract služby jsou operace kontraktu vyvolány synchronně spuštěním windows Communication Foundation (WCF), i když předchozí kroky klienta jsou vyvolány asynchronně na klientovi. Operace Multiply se Divide používají k asynchronnímu vyvolání služby na straně služby, i když je klient vyvolá synchronně. Tento příklad nastaví AsyncPattern vlastnost na true. Toto nastavení vlastnosti v kombinaci s implementací asynchronního vzoru rozhraní .NET Framework říká modulu runtime, aby operaci vyvolal asynchronně.

[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