tags:

views:

241

answers:

1

Hi

I want to ensure that a WCF-ServiceClient State will be closed after using the service.

I implemented the following Code to ensure that:

public static class ServiceClientFactory
{
    public static ServiceClientHost<T> CreateInstance<T>() where T : class, ICommunicationObject, new()
    {
        return new ServiceClientHost<T>();
    }
}

public class ServiceClientHost<T> : IDisposable where T : class, ICommunicationObject, new()
{
    private bool disposed;

    public ServiceClientHost()
    {
        Client = new T();
    }

    ~ServiceClientHost()
    {
        Dispose(false);
    }

    public T Client { get; private set; }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposeManagedResources)
    {
        if(!disposed)
        {
            if(disposeManagedResources)
            {
                Client.Close();
                Client = null;
            }
            disposed = true;
        }
    }
}

usage:

using (var host = ServiceClientFactory.CreateInstance<MySericeClient>())
{
   host.Client.DoSomething();
}

I was wondering if there is a better/elegant solution than mine?

Thanks for any hints!

+2  A: 

The use of the using block is generally a good idea with disposable objects - but not in the case of a WCF proxy. The trouble is that when closing the proxy (at the end of the using block), there's a good chance of an exception - which then goes unhandled (potentially) and the proxy isn't really closed.

Recommended best practice would be:

try
{
   var host = ServiceClientFactory.CreateInstance<MySericeClient>();

   ...... (use it).......

   host.Close();
}
catch(FaultException)
{   
   host.Abort();
}
catch(CommunicationException)
{
   host.Abort();
}

The trouble is - if anything does wrong during communication, your channel will be in a "faulted" state and calling ".Close()" on that channel will cause an exception.

Therefore, catch both the fault exceptions (signal from server something went wrong) and the CommunicationException (base class for Fault and other WCF client-side exceptions) and in that case, use proxy.Abort() to force an abort/close of the proxy (not waiting gracefully for the operation to complete, but just throwing in the sledgehammer).

Marc

marc_s