Procedura: chiamare le operazioni in modo asincrono tramite una channel factory
In questo argomento viene illustrato in che modo un client può accedere a un'operazione del servizio in modalità asincrona quando si utilizza un'applicazione client basata su ChannelFactory. Quando si utilizza un oggetto System.ServiceModel.ClientBase per richiamare un servizio, è possibile utilizzare il modello di chiamata asincrono basato su eventi. Per ulteriori informazioni, vedere Procedura: chiamare operazioni del servizio WCF in modo asincrono. Per ulteriori informazioni sul modello di chiamata asincrono basato su eventi, vedere Multithreaded Programming with the Event-based Asynchronous Pattern
Il servizio in questo argomento implementa l'interfaccia ICalculator
. Il client può chiamare in modo asincrono le operazioni su tale interfaccia, il che significa che le operazioni come Add
vengono suddivise in due metodi, BeginAdd
ed EndAdd
, il primo dei quali avvia la chiamata e il secondo recupera il risultato al termine dell'operazione. Per un esempio che illustra come implementare in modo asincrono un'operazione in un servizio, vedere Procedura: implementare un'operazione del servizio asincrona. Per informazioni dettagliate sulle operazioni sincrone e asincrone, vedere Operazioni sincrone e asincrone.
Procedura
Per chiamare operazioni del servizio WCF in modo asincrono
Eseguire lo Strumento ServiceModel Metadata Utility Tool (Svcutil.exe) con l'opzione /async come illustrato nel comando seguente.
svcutil /n:http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples https://localhost:8000/servicemodelsamples/service/mex /a
Questo genera una versione client asincrona del contratto di servizio per l'operazione.
Creare una funzione di callback da chiamare al temine dell'operazione asincrona, come illustrato nel codice di esempio seguente.
Private Shared Sub AddCallback(ByVal ar As IAsyncResult) Dim result = (CType(ar.AsyncState, CalculatorClient)).EndAdd(ar) Console.WriteLine("Add Result: {0}", result) End Sub
static void AddCallback(IAsyncResult ar) { double result = ((CalculatorClient)ar.AsyncState).EndAdd(ar); Console.WriteLine("Add Result: {0}", result); }
Per accedere in modo asincrono a un'operazione del servizio, creare il client, chiamare
Begin[Operation]
(ad esempio,BeginAdd
) e specificare una funzione di callback, come illustrato nel codice di esempio seguente.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)
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);
Quando la funzione di callback viene eseguita, il client chiama
End<operation>``EndAdd
(ad esempio, ) per recuperare il risultato.
Esempio
Il servizio utilizzato con il codice client della procedura precedente implementa l'interfaccia ICalculator
come illustrato nel codice seguente. Sul lato del servizio, le operazioni Add
e Subtract
del contratto vengono richiamate in modo sincrono dal runtime Windows Communication Foundation (WCF), anche se i passaggi client precedenti vengono richiamati in modo asincrono sul client. Le operazioni Multiply
e Divide
vengono utilizzate per richiamare il servizio in modo asincrono sul lato del servizio, anche se il client le richiama in modo sincrono. In questo esempio la proprietà AsyncPattern viene impostata su true. Tale impostazione della proprietà, in combinazione con l'implementazione del modello asincrono di .NET Framework, consente al runtime di richiamare in modo asincrono l'operazione.
<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
[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);
}