Резюме : Я полагаю, что наилучшей практикой является создание экземпляра клиента веб-службы, когда вы собираетесь его использовать, а затем выведение его из области видимости и сбор мусора.Это отражено в примерах, которые вы видите от Microsoft.Обоснование следует ...
Полный : Лучшее полное описание процесса, которое я нашел, находится на Как: получить доступ к службе из Silverlight .Здесь в примере показан типичный пример создания клиента веб-службы и разрешения ему выйти из области видимости (без необходимости его закрытия).Клиенты веб-сервисов наследуют от ClientBase, который имеет метод Finalize, который должен освобождать любые неуправляемые ресурсы, если это необходимо при сборке мусора.
У меня приличный опыт использования веб-сервисов, и я использую прокси и создаю их экземплярыпрямо перед использованием, а затем позвольте им собирать мусор.У меня никогда не было проблем с этим подходом.Я читал в блог Вэньлонга Донга , в котором говорилось, что создание прокси было дорогостоящим, но даже он говорит, что производительность улучшилась в .NET 3.5 (возможно, с тех пор она снова улучшилась?).Что я могу сказать вам, так это то, что производительность - это относительный термин, и если ваши извлекаемые данные не будут меньше тривиального размера, гораздо больше времени будет потрачено на сериализацию / десериализацию и передачу, чем на создание соединения.Это, конечно, мой опыт, и вам лучше сначала оптимизировать эти области.
Наконец, поскольку я считаю, что мое мнение до сих пор может быть недостаточным, я написал быстрый тест.Я создал веб-службу с поддержкой Silverlight, используя шаблон, поставляемый с Visual Web Developer 2010 Express (с методом void по умолчанию, называемым DoWork()
).Затем в моем примере клиента Silverlight я вызвал его, используя следующий код:
int counter=0;
public void Test()
{
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
client.DoWorkCompleted += (obj, args) =>
{
counter++;
if (counter > 9999)
{
for(int j=0;j<10;j++) GC.Collect();
System.Windows.MessageBox.Show("Completed");
}
};
client.DoWorkAsync();
}
Затем я вызвал метод Test с помощью for(int i=0;i<10000;i++) Test();
и запустил приложение.Потребовалось чуть более 20 секунд, чтобы загрузить приложение и завершить вызовы веб-службы (все 10000 из них).Когда выполнялись вызовы веб-службы, я увидел, что использование памяти для процесса превысило 150 МБ, но после завершения вызовов и вызова GC.Collect()
использование памяти сократилось до половины этой суммы.Это далеко не идеальный тест, и мне кажется, что он подтверждает, что память не просачивалась или пренебрежимо мала (учитывая, что, вероятно, нечасто вызывать 10 000 вызовов веб-служб, используя все экземпляры клиентов).Кроме того, это гораздо более простая модель, чем хранение прокси-объекта и необходимость беспокоиться о его сбое и повторном открытии.
Обоснование методологии тестирования: Мой тест сфокусирован на 2 потенциальных проблемах. Один из них - утечка памяти, а другой - процессорное время, затрачиваемое на создание и уничтожение объектов. Я рекомендую, чтобы было безопасно следовать примерам, предоставленным компанией (Microsoft), которая предоставляет классы. Если вас беспокоит эффективность сети, у вас не должно возникнуть проблем с моим примером, поскольку правильное создание / удаление этих объектов не повлияет на задержку сети. Если 99% затраченного времени составляет сетевое время, то оптимизация для теоретического улучшения в 1%, вероятно, расточительна с точки зрения времени разработки (если предположить, что есть даже преимущество, которое, я полагаю, мой тест ясно показывает, что мало / никто). Да, сетевые вызовы были локальными, что означает, что в течение 10 000 вызовов службы только около 20 секунд будет потрачено на ожидание объектов. Это составляет ~ 2 миллисекунды за вызов службы, затраченный на создание объектов. Что касается необходимости вызывать Dispose, я не имел в виду, что вы не должны вызывать его, просто это не показалось необходимым. Если вы забудете (или просто не захотите), мои тесты привели меня к мысли, что Dispose вызывался в Finalize для этих объектов. Даже в этом случае, вероятно, было бы более эффективно называть Dispose самостоятельно, но все же эффект незначителен. Для большинства разработок программного обеспечения вы получаете больше выгоды от разработки более эффективных алгоритмов и структур данных, чем от решения таких проблем (если только не происходит серьезная утечка памяти). Если вам требуется более высокая эффективность, возможно, вам не следует использовать веб-службы, поскольку есть более эффективные варианты передачи данных, чем в системе, основанной на XML.