处置/清理Web服务代理

时间:2013-05-03 09:42:08

标签: c# asp.net webservice-client

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

如果代理类派生自SoapHttpClientProtocolClientBase<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服务代理?

1 个答案:

答案 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;
}