我想覆盖生成的代理(ClientBase
)的Dispose方法,因为处理代理会调用Close,并且当通道出现故障时可能会抛出异常。
我提出的唯一方法是为我生成的代理创建一个部分类,使其继承自IDisposable
:
public partial class MyServiceProxy : IDisposable
{
#region IDisposable Members
public void Dispose()
{
if (State != System.ServiceModel.CommunicationState.Faulted)
Close();
else
Abort();
}
#endregion
}
我做了一些测试,确实调用了我的Dispose
方法。
您认为此策略存在任何问题吗?
另外,我不喜欢我必须为每个生成的代理创建这个分部类的事实。
如果我能够从基类继承代理,那就太好了......
答案 0 :(得分:2)
它没有问题。以这种方式自定义设计器生成的代码正是部分类要提供的功能,这是处理IDisposable
上损坏的ClientBase
实现的推荐方法之一。
至于必须为每个WCF客户端重新实现此代码 - 不幸的是,如果您想使用IDisposable
模式,那么您将会这样做。您可以将if/else
块提取到实用程序方法中,但仍然需要为每个块创建一个部分类并覆盖Dispose
。
看到上述内容相当繁琐,许多人选择使用Service Proxy Helper,因为它不需要编写任何新代码。
我使用稍微修改过的版本,我自己:
public static class Service<TProxy>
where TProxy : ICommunicationObject, IDisposable, new()
{
public static void Using(Action<TProxy> action)
{
TProxy proxy = new TProxy();
bool success = false;
try
{
action(proxy);
proxy.Close();
success = true;
}
finally
{
if (!success)
{
proxy.Abort();
}
}
}
}
允许编写这种代码:
Service<MyServiceClient>.Using(svc => svc.PerformOperation());
或者:
Service<MyServiceClient>.Using(svc =>
{
var result = svc.PerformOperation();
ProcessResult(result);
});
注意:WCF代理的创建成本很高,因此您通常希望尽可能长时间地保持它们的存活,而不是每隔几秒(或更多)创建和处理它们。这适用于不经常使用的客户端。
答案 1 :(得分:1)
重写Dispose()方法是一种完全有效的策略。
此问题的答案中还有其他一些选项:What is the best workaround for the WCF client `using` block issue?