What is the best practise for Disposing/Cleaning up a web service proxy instance after synchronous usage?
How does the answer differ if the proxy class is derived from SoapHttpClientProtocol
versus ClientBase<T>
?
Background
I'm trying to figure out why one of my WCF web services sometimes seems to get into a state where it no longer reponds to service calls. Basically it seems like it hangs and for now I don't really have any hard data to figure out what's going on when this occurrs.
One thing that I suspect might be an issue is the fact that this WCF service is itself doing web service calls to a few other services. These other services are called (synchronously) using proxies that are derived from SoapHttpClientProtocol
(made using wsdl.exe) and at this time these proxy instances are left to be cleaned up by the finalizer:
...
var testProxy = new TestServiceProxy();
var repsonse = testProxy.CallTest("foo");
// process the reponse
...
So should I simply wrap these up in a using(...) { ... }
block?
...
using(var testProxy = new TestServiceProxy())
{
var repsonse = testProxy.CallTest("foo");
// process the reponse
}
...
What if I were to change these proxy classes to be based on ClientBase<T>
by recreating them using svcutil.exe
? Based on my research so far, it seems the Dipose()
method of classes derived from ClientBase<T>
will internally call the Close()
method of the class and this method might in turn throw exceptions. So wrapping a proxy based on ClientBase<T>
in a Using()
is not always safe.
So to reiterate the question(s):
SoapHttpClientProtocol
?ClientBase<T>
?Based on my best efforts to find the answer to this question, I'd say that for SoapHttpClientProtocol
based proxies (regular .asmx web service proxies) the correct way is to simly wrap it in using()
:
using(var testProxy = new TestAsmxServiceProxy())
{
var response = testProxy.CallTest("foo");
// process the reponse
}
For proxies based on ClientBase<T>
(WCF proxies) the answer is that it should not be wrapped in a using()
statement. Instead the following pattern should be used (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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With