同步使用后处理/清理Web服务代理实例的最佳做法是什么?
如果代理类派生自SoapHttpClientProtocol
与ClientBase<T>
,答案会有何不同?
背景
我正在试图找出为什么我的某个WCF Web服务有时会进入一个不再响应服务调用的状态。基本上它似乎挂了,现在我真的没有任何硬数据来弄清楚发生这种情况时会发生什么。
我怀疑可能存在的一个问题是,这个WCF服务本身正在对其他一些服务进行Web服务调用。使用从SoapHttpClientProtocol
派生的代理(使用wsdl.exe制作)调用(同步)这些其他服务,此时这些代理实例将由终结器清理:
...
var testProxy = new TestServiceProxy();
var repsonse = testProxy.CallTest("foo");
// process the reponse
...
我应该将它们简单地包装在using(...) { ... }
块中吗?
...
using(var testProxy = new TestServiceProxy())
{
var repsonse = testProxy.CallTest("foo");
// process the reponse
}
...
如果我要使用ClientBase<T>
重新创建这些代理类以基于svcutil.exe
更改它们,该怎么办?根据我到目前为止的研究,似乎从Dipose()
派生的类的ClientBase<T>
方法将在内部调用类的Close()
方法,并且此方法可能反过来抛出异常。因此,在ClientBase<T>
中基于Using()
打包代理并不总是安全的。
重申问题:
SoapHttpClientProtocol
时,如何在使用后清理我的Web服务代理?ClientBase<T>
时,如何在使用后清理我的Web服务代理?答案 0 :(得分:13)
根据我尽最大努力找到这个问题的答案,我会说基于SoapHttpClientProtocol
的代理(常规的 .asmx Web服务代理),正确的方法是模拟将其包装在using()
:
using(var testProxy = new TestAsmxServiceProxy())
{
var response = testProxy.CallTest("foo");
// process the reponse
}
对于基于ClientBase<T>
( WCF 代理)的代理,答案是它不应该包含在using()
语句中。相反,应使用以下模式(msdn reference):
var client = new TestWcfServiceProxy();
try
{
var response = client.CallTest("foo");
client.Close();
// process the response
}
catch (CommunicationException e)
{
...
client.Abort();
}
catch (TimeoutException e)
{
...
client.Abort();
}
catch (Exception e)
{
...
client.Abort();
throw;
}