我想确保在使用该服务后关闭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();
}
我想知道是否有比我更好/更优雅的解决方案?
感谢任何提示!
答案 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()来强制中止/关闭代理(没有优雅地等待操作完成,但只是扔在大锤中)。
马克