BlogServiceHost.Create()

WCF & Friends - Il blog di Fabio Cozzolino

Recent Posts

Tags

News

Community

Email Notifications

6 Guys

Blogroll Italiani

Archives

[WCF] Chiudere correttamente il client

Uno degli usi più comuni ed allo stesso tempo più errati di un client WCF è l’utilizzo di un blocco using. Vediamo perchè un codice come questo è errato:

  1: using (MyClient client = new MyClient())
  2: {
  3:     client.RemoteOperation();
  4: }

che, quando compilato, viene tradotto in questo:

  1: MyClient client = new MyClient();
  2: try
  3: {
  4:     client.RemoteOperation();
  5: }
  6: finally
  7: {
  8:     ((IDisposable)client).Dispose();
  9: }

Qui, però, abbiamo un problemino. Se il client termina correttamente la chiamata, infatti, la dispose tenta di chiudere il channel, e questo è giusto. Ma se la comunicazione va in eccezione, allora la dispose tenterà comunque di chiudere il channel, generando quindi una nuova eccezione proprio perchè un channel in stato Faulted non può passare in stato Closed. L’eccezione generata è infatti:

The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.

Come fare quindi? Semplice non usare lo using e “tornare” al classico “try..catch” esplicito:

  1: MyClient client = new MyClient();
  2: try
  3: {
  4:     client.RemoteOperation();
  5:     client.Close();
  6: }
  7: catch (Exception ex)
  8: {
  9:     client.Abort();
 10: }

in questo modo chiudiamo correttamente il channel mettendolo in Closed, effettuando però una serie di operazioni come il disposing dei vari channel utilizzati, la chiusura della sessione corrente (se utilizzata), la chiusura di eventuali transazioni ancora in piedi, etc….

Queste stesse operazioni vengono eseguite anche dalla close, ma chiaramente con le differenze del caso dovute alle specifiche implementazioni dei vari channel coinvolti. Tenendo presente come è composto il channel layer di WCF, è chiaro che quando viene invocato l’Abort o il Close sul client, questo viene propagato verso tutti i vari channels, generando quindi comportamenti differenti sulla base dello specifico channel.

Alcuni riferimenti:
http://msdn.microsoft.com/en-us/library/aa355056.aspx
http://msdn.microsoft.com/en-us/library/aa354510.aspx

Posted: Apr 14 2009, 09:52 PM by Fabio.Cozzolino | with no comments
Filed under: