DarioSantarelli.Blog("UgiDotNet");

<sharing mode=”On” users=”*” />
posts - 176, comments - 105, trackbacks - 3

My Links

News


This is my personal blog. These postings are provided "AS IS" with no warranties, and confer no rights.




Tag Cloud

Archives

Post Categories

My English Blog

[WCF] Operazioni asincrone client-side

WCF è un framework concepito per sviluppare scenari di comunicazione completamente disaccoppiati sotto ogni punto di vista. In particolare, per quanto riguarda la sincronizzazione dei messaggi, è prevista internamente una rigida implementazione di pattern asincroni per ottenere chiamate non bloccanti tra i vari livelli strutturali. Esternamente, invece, WCF espone possibilità di programmazione asincrona sia client-side che server-side. L'aspetto interessante da approfondire in merito è come il programming model asincrono client-side non abbia nulla a che vedere con quello server-side: ovvero, un client può sostanzialmente invocare in modo asincrono un servizio indipendentemente dal fatto che esso sia implementato con un pattern sincrono piuttosto che asincrono.
Il disaccoppiamento avviene infatti a livello di trasporto quando i dati vengono serializzati/deserializzati.
Per capire l’importanza di tale feature pensiamo semplicemente ad un’ architettura N-tier che poggia su WCF: potremmo avere diverse “operation” che a loro volta utilizzano proxy client verso altre operation WCF, rendendo vitale l’utilizzo di pattern di comunicazione asincroni. 
Vediamo un semplice esempio. Supponiamo di avere il seguente ServiceContract:

[ServiceContract]
public interface IAuthentication
{
 
[OperationContract]
 
UserInfo Login(string username, string password);       

 
[OperationContract]
 
void Logout(string username);
}
   

Se lato client utilizzassimo Svcutil ( con gli opportuni parametri ) o il solito “Add Service Reference” di VisualStudio, otterremmo la generazione automatica del seguente object model:

 

Come si può osservare abbiamo una versione asincrona client-side del ServiceContract (IAuthentication), un' interfaccia <ServiceContract>Channel (IAuthenticationChannel) ed una classe Client (AuthenticationClient) che espone metodi di invocazione sia asincroni che sincroni. Nello specifico, si prospettano due possibili modalità di invocazione asincrona client-side di un’ operation:

1. Invocazione asincrona “event-based” (o “event-driven”) 
E' la modalità più semplice e raccomandata poiché richede solamente l’aggiunta di un EventHandler per ricevere una notifica all’occorrenza di una risposta. Questa modalità ( disponibile solo nel framework 3.5 e comunque solo per questo tipo di invocazione ) permette di sfruttare l’approccio asincrono event-based tramite un metodo nella forma <operationName>Async e l’intercettazione di un evento <operationName>Completed al cui interno si ha accesso al risultato dell’invocazione <operationName>CompletedEventArgs.

...

ServiceReference.AuthenticationClient client = new ServiceReference.AuthenticationClient();
client.LoginCompleted += new EventHandler<ServiceReference.LoginCompletedEventArgs>(client_LoginCompleted);
client.LoginAsync("dario.santarelli", "password");

Console.ReadLine();

client.Close();

...

protected void client_LoginCompleted(object sender, ServiceReference.LoginCompletedEventArgs e)
{
 
UserInfo info = e.Result as UserInfo;
 
Console.WriteLine(string.Format("UserName: {0} - Password: {1}",info.UserName,info.Email));
}

  

2. Invocazione asincrona via ChannelFactory
Il pattern asincrono previsto in questa modalità è quello classico previsto a partire dal framework 1.1: tramite lo split di un operation in due metodi ( Begin<operationName> e End<operationName> ), si sfruttano oggetti che implementano l’interfaccia System.IAsyncResult per rappresentare lo stato di una operazione asincrona.

...

EndpointAddress endpointAddress = new EndpointAddress("http://.../AuthenticationService.svc");
ServiceReference.IAuthenticationChannel channelClient = ChannelFactory<ServiceReference.IAuthenticationChannel>.CreateChannel(new BasicHttpBinding(), endpointAddress);
IAsyncResult result = channelClient.BeginLogin("dario.santarelli", "password", LoginCallBack, channelClient);

Console.ReadLine();

channelClient.Close();
channelClient.Dispose();

...  

protected void LoginCallBack(IAsyncResult ar)
{
 
UserInfo result = ((ServiceReference.IAuthenticationChannel)ar.AsyncState).EndLogin(ar);
 
Console.WriteLine("Result: {0}", result.UserName);
}


Conclusioni
In entrambe le soluzioni presentate, una nostra application può invocare un’operazione in maniera asincrona anche se il servizio è implementato in maniera sincrona, allo stesso modo con cui una applicazione può usare lo stesso pattern per invocare in maniera asincrona un metodo sincrono locale. “Come” è poi implementato l’ OperationContract è assolutamente insignificante per il client.


Risorse MSDN:

 

Technorati Tag: ,

Print | posted on Monday, February 9, 2009 11:24 PM | Filed Under [ WCF ]

Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET