2015. december 17., csütörtök

Using és a WCF kliens

Minden IDisposable implementációnál szükséges meghívni a Dispose metódust, hogy felszabadítsuk az erőforrásokat. Kézenfekvő megoldás rá a using blokk használata, mivel egy "finally" ágban automatikusan meghívja. Azonban egy WCF kliensnél a Dispose hívás egyenértékű azzal, hogy a csatornára hívunk egy Close-t. Ez viszont bármikor hibát dobhat, például akkor, hogy a csatorna Faulted állapotban van, mivel olyankor Abortot kellene hívni. Bővebb leírást egy MSDN bejegyzés tartalmaz.

Szerencsére az IDisposable.Dispose virtuális, így felül lehet definiálni. Mivel a generált WCF kliens osztály partial class, így könnyedén elérhető, hogy a using Dispose hívása ne dobjon hibát. Ennek eredménye, hogy ténylegesen a Faulted állapotot kiváltó hibaüzenetet fogjuk megkapni.

Az alábbi partial class-t kell létrehozni, ami nyugodtan implementálhatja az IDisposable interfészt, mivel a ClientBase nem teszi.

public partial class CalculatorClient : IDisposable
{
    #region IDisposable implementation
    void IDisposable.Dispose()
    {
        Dispose(true)
    }
 
    /// <summary>
    /// Dispose hívás. 
    /// Értelmesen kezeli a lezárást akkor is, ha a faulted állapotban van.
    /// </summary>
    /// <param name="disposing">Dispose? (másik lehetőség a Finalizing)</param>
    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            try
            {
                if (State != CommunicationState.Faulted)
                {
                    Close();
                }
            }
            finally
            {
                if (State != CommunicationState.Closed)
                {
                    Abort();
                }
            }
        }
    }
 
    ~CalculatorClient()
    {
        Dispose(false);
    }
 
    #endregion
}

Ehhez továbbá engedélyezni kell a service app.configjában lévő megfelelő ServiceBehavior szekcióban is, hogy benne legyen a hibaüzenet a válaszban. Enélkül csak olyan hibaüzenet jelenik meg, hogy nem sikerült feldolgozni a hibát, mivel nincs bekapcsolva, hogy legyen benne a válaszban.

<serviceBehaviors>
   <behavior>
     <serviceDebug includeExceptionDetailInFaults="true"/>
   </behavior>
</serviceBehaviors>

Nincsenek megjegyzések:

Megjegyzés küldése