5

同步使用后处置/清理 Web 服务代理实例的最佳实践是什么?

如果代理类是从SoapHttpClientProtocolvs派生的,答案有什么不同ClientBase<T>

背景

我试图弄清楚为什么我的 WCF Web 服务之一有时似乎会进入不再响应服务调用的状态。基本上它似乎挂起,现在我真的没有任何硬数据来弄清楚发生这种情况时发生了什么。

我怀疑可能是一个问题的一件事是,这个 WCF 服务本身正在对其他一些服务进行 Web 服务调用。使用派生自(使用 wsdl.exe 生成)的代理(同步)调用这些其他服务,SoapHttpClientProtocol此时这些代理实例由终结器清理:

...
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>a包装代理Using()并不总是安全的。

因此,重申问题:

  • 当代理基于时,我应该如何清理我的网络服务代理SoapHttpClientProtocol
  • 当代理基于时,我应该如何清理我的网络服务代理ClientBase<T>
4

1 回答 1

14

基于我为找到这个问题的答案所做的最大努力,我会说对于SoapHttpClientProtocol基于代理(常规.asmx Web 服务代理),正确的方法是将其简单地包装在using()

using(var testProxy = new TestAsmxServiceProxy())
{
    var response = testProxy.CallTest("foo");

    // process the reponse
}

对于基于ClientBase<T>WCF代理)的代理,答案是它不应该包含在using()语句中。相反,应使用以下模式(msdn 参考):

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;
}
于 2013-05-31T10:25:38.783 回答