2

2 small parts to this question which hopefully will clear up some ambiguity for me.

Firstly, which is better for calling a WCF service?

using (var myService = new ServiceClient("httpBinding")){
     try{         
          var customerDetails = GetCustomerDetails();
          var results = myService.GetCustomerPurchases(customerDetails);
     }catch(Exception e){
          ......
     }
}

or

var myService = new ServiceClient("httpBinding");
try{
     var customerDetails = GetCustomerDetails();
     var results = myService.GetCustomerPurchases(customerDetails);
}catch(Exception e){
     .......
}

What I'm wondering is, should I always be wrapping my service call in a using block? Does IDisposable.Dispose() get called if the service throws an exception?

Chris
  • 2,471
  • 25
  • 36

2 Answers2

4

Have a look at this question.

Also you can create a couple of classes like

public class ClientService<TProxy>
{
    private static ChannelFactory<TProxy> channelFactory = new ChannelFactory<TProxy>("*");

    public static void SendData(Action<TProxy> codeBlock)
    {
        var proxy = (IClientChannel) channelFactory.CreateChannel();
        bool success = false;

        try
        {
            codeBlock((TProxy)proxy);
            proxy.Close();
            success = true;
        }
        finally
        {
            if (!success)
            {
                proxy.Abort();
            }
        }
    }

    public static TResult GetData<TResult>(Func<TProxy, TResult> codeBlock)
    {
        var proxy = (IClientChannel) channelFactory.CreateChannel();
        bool success = false;

        TResult result;
        try
        {
            result = codeBlock((TProxy)proxy);
            proxy.Close();
            success = true;
        }
        finally
        {
            if (!success)
            {
                proxy.Abort();
            }
        }

        return result;
    }
}

public class SomeAnotherService<TProxy>
{
    public static bool SendData(Action<TProxy> codeBlock)
    {
        try
        {
            ClientService<TProxy>.SendData(codeBlock);
            return true;
        }
        catch(Exception ex)
        {
            //...
        }
        return false;
    }

    public static TResult GetData<TResult>(Func<TProxy, TResult> codeBlock)
    {
        TResult result = default(TResult);
        try
        {
            result = ClientService<TProxy>.GetData(codeBlock);
        }
        catch (Exception ex)
        {
            //...
        }

        return result;
    }
}

Sometimes it's convenient. Here is an example of calling some service method.

var someObj = SomeAnotherService<IMyService>.GetData(x => x.SomeMethod());
Community
  • 1
  • 1
Alex Kovanev
  • 1,858
  • 1
  • 16
  • 29
2

Do not use using when dealing with WCF proxies. One of the reasons is Dispose() will call Close() which will throw an exception if the proxy is on Faulted state. So the best use will be something like this:

var myService = new ServiceClient("httpBinding");

try
{
    myService.SomeMethod();
}
catch
{
    // in case of exception, always call Abort*(
    myService.Abort();

    // handle the exception
    MessageBox.Show("error..");
}
finally
{
    myService.Close();
}
Hutch
  • 7
  • 3