Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disposing/Cleaning up web service proxies

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):

  • How should I clean up my web service proxy after using it when the proxy is based on SoapHttpClientProtocol?
  • How should I clean up my web service proxy after using it when the proxy is based on ClientBase<T>?
like image 340
user1429080 Avatar asked May 03 '13 09:05

user1429080


1 Answers

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;
}
like image 129
user1429080 Avatar answered Nov 20 '22 13:11

user1429080