Reputation: 2481
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?
Upvotes: 2
Views: 5324
Reputation:
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();
}
Upvotes: 2
Reputation: 1888
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());
Upvotes: 4