2013-05-03 139 views
5

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

如果代理类是从SoapHttpClientProtocolClientBase<T>派生出来的,答案会有什么不同?

背景

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

我怀疑可能是一个问题的一件事是,这个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 
} 
... 

如果我是通过使用svcutil.exe重建他们根据ClientBase<T>更改这些代理类?根据我迄今为止的研究,似乎从ClientBase<T>派生的类的Dipose()方法将在内部调用该类的Close()方法,并且此方法可能会反过来抛出异常。因此,将基于ClientBase<T>的代理包装在Using()中并不总是安全的。

所以要重申的问题(S):

  • 我应该如何清理我的web服务代理时,代理是基于SoapHttpClientProtocol使用后?
  • 当代理基于ClientBase<T>时,我应该如何清理我的Web服务代理?基于找到这个问题的答案我尽了最大努力

回答

12

,我会说,对于SoapHttpClientProtocol基于代理(常规的.asmx Web服务代理)的正确方法是simly包装在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; 
} 
+0

我不确定这个的第一部分。 'Dispose'由'Component'实现,但'Abort'由'WebClientProtocol'实现。看看代码,看起来'Dispose'不知道请求。 https://msdn.microsoft.com/en-us/library/ff647786.aspx似乎支持(在“Web服务呼叫完成之前超时的ASP.NET页的中止连接”)。 对于WCF,请参阅https://stackoverflow.com/questions/573872/what-is-the-best-workaround-for-the-wcf-client-using-block-issue – TrueWill 2017-06-07 16:05:53