“Oprava” IDisposible u WCF proxy clienta

Tomáš Holan       9. 1. 2011       WCF/WS       6128 zobrazení

Pokud voláme WCF službu pomoci vygenerovaného proxy clienta (např. přidáním service reference do svého projektu) a volání provádíme správně, tak zásadně nepoužíváme blok using resp. volání metody Dispose() na instanci naší client třídy. Důvody jsou hned dva a jsou docela dobře popsány např. zde na MSDN. Namísto toho jsme nuceni používat fragment podobný tomuto:

using System;
using System.ServiceModel;

//...

var client = new ServiceClient();
try
{
    //Use client instance
    //...
    client.Close();
}
catch (CommunicationException e)
{
    //...  
    client.Abort();
}
catch (TimeoutException e)
{
    //...  
    client.Abort();
}
catch (Exception e)
{
    //...  
    client.Abort();
    throw;
}

Přestože toto již pravděpodobně funguje (pokud výjimky CommunicationException  a TimeoutException  ošetříme správně apod.), ale minimálně to není moc hezké a také pokud budeme mít ve své WCF službě metod vícero bude kód i poměrně dlouhý.

Lepším řešením by ale bylo vygenerovaného klienta nějak “opravit”, aby se dala jednotlivá volání pokud možno zjednodušit. A to je přesně to co lze a my teď uděláme. Využijeme toho, že klient je vygenerovaný jako partial třída a můžeme k ní tedy dopisovat vlastní kód a v tomto  případě to bude naše vlastní implementace metody Dispose(). Do projektu tedy přidáme nový soubor, pojmenujeme ho podle názvu třídy našeho klienta (pro příklad výše to je ServiceClient.cs) a vložíme do něho tento kód:

using System;
using System.ServiceModel;

namespace ServiceClientProxy
{
    public partial class ServiceClient : IDisposable
    {
        #region action methods
        public void Dispose()
        {
            try
            {
                if (this.State != CommunicationState.Faulted &&
                    this.State != CommunicationState.Closed)
                {
                    this.Close();
                }
                else
                {
                    this.Abort();
                }
            }
            catch (CommunicationException)
            {
                this.Abort();
            }
            catch (TimeoutException)
            {
                this.Abort();
            }
            catch (System.Exception)
            {
                this.Abort();
                throw;
            }
        }
        #endregion
    }
}

(obecně zde stačí změnit namespace a jméno třídy clienta)

POZOR: Nezapomeňte u deklarace naší části partial třídy vždy uvést, že implementuje interface IDisposable, jinak nebude naše implementace metody Dispose použita a výsledkem bude chybný kód!

Volání WCF služby pak můžeme provádět již opět velmi elegantně takto:

using (var client = new ServiceClient())
{
    //Use client instance
    //...
}

(Pokud si budete chtít vyzkoušet, že se skutečně volá naše nová implementace metody Dispose(), budete potřebovat ve vygenerované třídě clienta zaremovat atribut [System.Diagnostics.DebuggerStepThroughAttribute()] v její deklaraci, aby šlo do této metody umístit breakpoint.)

A to je vše, na shledanou zas někdy příště.

 

hodnocení článku

0 bodů / 1 hlasů       Hodnotit mohou jen registrované uživatelé.

 

Nový příspěvek

 

                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback