同步使用后处置/清理 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 服务代理? ?
最佳答案
根据我为找到这个问题的答案所做的最大努力,我会说 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;
}
关于c# - 处理/清理网络服务代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16355941/