2012-01-30 15 views

risposta

8

Anche se non strettamente rivolta al canale, è possibile fare:

ChannelFactory<IMyService> channelFactory = null; 
try 
{ 
    channelFactory = 
     new ChannelFactory<IMyService>(); 
    channelFactory.Open(); 

    // Do work... 

    channelFactory.Close(); 
} 
catch (CommunicationException) 
{ 
    if (channelFactory != null) 
    { 
     channelFactory.Abort(); 
    } 
} 
catch (TimeoutException) 
{ 
    if (channelFactory != null) 
    { 
     channelFactory.Abort(); 
    } 
} 
catch (Exception) 
{ 
    if (channelFactory != null) 
    { 
     channelFactory.Abort(); 
    } 
    throw; 
} 
+0

Questa risposta è un po 'spenta: fornisce un modello di utilizzo per ChannelFactory, mentre la domanda originale riguarda il canale. Mentre è vero (credo) che la chiusura della fabbrica chiuderà tutti i canali che ha creato, uno schema più comune è quello di mantenere una channelFactory aperta in modo che possa creare più canali in modo efficiente. Ogni canale dovrebbe essere chiuso individualmente mantenendo la fabbrica aperta per il lavoro. –

+0

Questo è vero, grazie per averlo indicato. Ho post modificato per riflettere –

+0

@ ÖrjanJämte grazie aggiornato –

17

Che usato per essere il modo comunemente accettato di rilasciare deleghe client WCF nei "primi" giorni di WCF.

Tuttavia le cose sono cambiate. Si è scoperto che l'implementazione di IClientChannel<T>.Dispose() invoca semplicemente il metodo IClientChannel<T>.Close(), che in alcune circostanze, può generare un'eccezione, ad esempio quando il canale sottostante non è aperto o non può essere chiuso in modo tempestivo.

Pertanto non è una buona idea invocare Close() all'interno di un blocco catch poiché ciò potrebbe lasciare alcune risorse non pubblicate in caso di un'eccezione.

La nuovo modo consigliato è invocare IClientChannel<T>.Abort() all'interno del blocco catch invece, in caso Close() fallirebbe. Ecco un esempio:

try 
{ 
    channel.DoSomething(); 
    channel.Close(); 
} 
catch 
{ 
    channel.Abort(); 
    throw; 
} 

Aggiornamento:

Ecco un riferimento a un articolo di MSDN che describes this recommendation.

+0

Devo davvero chiudere il canale? Sto pensando di lasciarlo aperto e la prossima volta che lo uso, controllo se factory.State! = CommunicationState.Opened (pipe factory nel mio caso) e se è vero, quindi ricrea il canale. – Valentin

+1

@Valentin La risposta breve è ** sì **, si * dovrebbe * rilasciare un canale WCF * esplicitamente * quando non è più necessario. Un canale WCF aperto contiene alcune risorse di livello inferiore, come un socket TCP o una connessione HTTP. Se ritardate il rilascio di queste risorse lasciandole nelle mani * non deterministiche * di Gargage Collector, potreste imbattervi in ​​una situazione in cui diventano scarse, il che renderebbe impossibile la creazione di nuovi canali. –

+0

Hai qualche riferimento ai documenti che descrivono questo cambio di raccomandazione? – Macke

Problemi correlati