用于关闭ServiceClient状态的模式

时间:2009-09-04 10:59:54

标签: c# wcf design-patterns

我想确保在使用该服务后关闭WCF-ServiceClient状态。

我实施了以下守则以确保:

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;
        }
    }
}

用法:

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

我想知道是否有比我更好/更优雅的解决方案?

感谢任何提示!

1 个答案:

答案 0 :(得分:2)

对于一次性对象,使用using块通常是一个好主意 - 但不是在WCF代理的情况下。问题在于,当关闭代理时(在使用块的末尾),很有可能出现异常 - 然后无法处理(可能)并且代理并未真正关闭。

建议的最佳做法是:

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

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

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

问题是 - 如果在通讯过程中出现任何问题,您的频道将处于“故障”状态,并且在该频道上调用“.Close()”将导致异常。

因此,捕获故障异常(来自服务器的信号出错)和CommunicationException(Fault和其他WCF客户端异常的基类),在这种情况下,使用proxy.Abort()来强制中止/关闭代理(没有优雅地等待操作完成,但只是扔在大锤中)。

马克