Как вызвать метод веб-службы в C#
Я хочу знать, как безопасно вызывать метод веб-службы WCF. Являются ли оба эти метода приемлемыми / эквивалентными? Есть ли способ лучше?
1-й способ:
public Thing GetThing()
{
using (var client = new WebServicesClient())
{
var thing = client.GetThing();
return thing;
}
}
2-й способ:
public Thing GetThing()
{
WebServicesClient client = null;
try
{
client = new WebServicesClient();
var thing = client.GetThing();
return thing;
}
finally
{
if (client != null)
{
client.Close();
}
}
}
Я хочу убедиться, что клиент правильно закрыт и утилизирован.
Спасибо
3 ответа
С помощью using
(без каламбура) не рекомендуется, потому что даже Dispose()
может бросить исключения.
Вот пара методов расширения, которые мы используем:
using System;
using System.ServiceModel;
public static class CommunicationObjectExtensions
{
public static void SafeClose(this ICommunicationObject communicationObject)
{
if(communicationObject.State != CommunicationState.Opened)
return;
try
{
communicationObject.Close();
}
catch(CommunicationException ex)
{
communicationObject.Abort();
}
catch(TimeoutException ex)
{
communicationObject.Abort();
}
catch(Exception ex)
{
communicationObject.Abort();
throw;
}
}
public static TResult SafeExecute<TServiceClient, TResult>(this TServiceClient communicationObject,
Func<TServiceClient, TResult> serviceAction)
where TServiceClient : ICommunicationObject
{
try
{
var result = serviceAction.Invoke(communicationObject);
return result;
} // try
finally
{
communicationObject.SafeClose();
} // finally
}
}
С этими двумя:
var client = new WebServicesClient();
return client.SafeExecute(c => c.GetThing());
Второй способ немного лучше, поскольку вы справляетесь с тем фактом, что может возникнуть исключение. Если вы поймали в ловушку и хотя бы зарегистрировали конкретное исключение, это было бы лучше.
Однако этот код будет блокироваться до GetThing
возвращается. Если это быстрая операция, то это может не быть проблемой, но в противном случае лучшим подходом будет создание асинхронного метода для получения данных. Это вызывает событие, указывающее на завершение, и вы подписываетесь на это событие, чтобы обновить пользовательский интерфейс (или все, что вам нужно сделать).
Не совсем:
- 2-й способ не избавляет () вашего клиента
- Использование не очистит должным образом, если есть ошибка См. http://geekswithblogs.net/bcaraway/archive/2008/07/06/123622.aspx