Медленный первый вызов веб-службы C #

Я пытаюсь получить доступ к веб-службам PubMed, как указано здесь:

http://www.ncbi.nlm.nih.gov/entrez/eutils/soap/v2.0/DOC/esoap_help.html.

Я написал код на java для доступа к веб-сервису, и время возврата было порядка менее 1 секунды. Я написал код на C # для доступа к той же веб-службе, и время возврата было порядка 12 секунд для первоначального вызова, а затем менее 1 секунды для всех последующих вызовов.

Я пытался писать в веб-службу на C # двумя способами - как в виде консольных приложений. Сначала был стандартный метод «щелкнуть правой кнопкой мыши по ссылкам и сделать« Добавить ссылку на службу »», который добавит информацию в app.config, и вы сможете сделать вызовы красивыми и простыми. Во-вторых, использовать wsdl.exe для создания dll и максимально «прямого» доступа к веб-службе (без мастеров). Оба способа дают одинаковый результат. Я опубликую оба соответствующих фрагмента кода.

1) (из мастера добавления ссылки на службу)

http://www.ncbi.nlm.nih.gov/entrez/eutils/soap/v2.0/efetch_pubmed.wsdl (as Namespace: PubMedWebServiceEfetch_pubMed)

(в коде)

Stopwatch sw = new Stopwatch();
PubMedWebServiceEfetch_pubMed.eUtilsServiceSoapClient server = new PubMedWebServiceEfetch_pubMed.eUtilsServiceSoapClient();
try
{
    PubMedWebServiceEfetch_pubMed.eFetchRequest searchRequest = new PubMedWebServiceEfetch_pubMed.eFetchRequest();
    searchRequest.id = "11850928";
    Console.WriteLine("Run server.run_eFetch(theRequest).  [Reset stopwatch]");
    sw.Restart();
    PubMedWebServiceEfetch_pubMed.eFetchResult searchResult = server.run_eFetch(searchRequest);
    Console.WriteLine(searchResult.Count() + " - elapsed milliseconds = " + sw.ElapsedMilliseconds);
    sw.Stop();
}
catch (Exception e1) { Console.WriteLine(e1); }
finally { server.Dispose(); } 

2) (из командной строки)

wsdl /out:myProxyClassPubMed.cs http://eutils.ncbi.nlm.nih.gov/soap/v2.0/efetch_pubmed.wsdl
csc /t:library MyProxyClassPubMed.cs

(добавить dll в консольное приложение)

Stopwatch sw = new Stopwatch();
eFetchPubmedService service = new eFetchPubmedService();
try
{
    eFetchRequest theRequest = new eFetchRequest();
    theRequest.id = "11850928";
    Console.WriteLine("Run service.run_eFetch(theRequest).  [Reset stopwatch]");
    sw.Restart();
    eFetchResult searchResult = service.run_eFetch(theRequest);
    Console.WriteLine(searchResult.Count() + " - elapsed milliseconds = " + sw.ElapsedMilliseconds);
    sw.Stop();
}
catch (Exception e1) { Console.WriteLine(e1); }
finally { service.Dispose(); }

После долгих поисков я обнаружил, что вы должны иметь возможность использовать sgen для создания сериализатора XML. Я побежал:

sgen /a:myProxyClassPubMed.dll /f

В результате была создана dll myProxyClassPubMed.XmlSerializers.dll, которую я затем добавил в качестве ссылки во втором типе подключения.

Я также испортил опцию «Создать сериализацию сборки» в области сборки приложения и не нашел улучшений.

Я хотел бы выполнять эти вызовы веб-служб через страницу ASP.NET, поэтому время возврата в двенадцать секунд при первом вызове недопустимо.

Я подумал о том, чтобы разместить это на BioStar, но он не так популярен, как этот форум. Я могу это сделать, если здесь не найду ответов.

Любые идеи?


person chi-hawk    schedule 23.01.2012    source источник
comment
Как размещается ваша служба WCF? Если вы размещаете в IIS, то есть вероятность, что первый вызов должен развернуть всю инфраструктуру времени выполнения WCF (ServiceHost и т. Д.). Это будет дороже, чем любые последующие звонки ...   -  person marc_s    schedule 23.01.2012
comment
@marc_s Все это делается в консольном приложении на моей стороне. Я еще не запускаю его на странице ASP.NET   -  person chi-hawk    schedule 23.01.2012


Ответы (1)


Первый вызов открывает канал (что относительно дорого), а второй вызов использует уже открытый канал (дешевле).

person RQDQ    schedule 23.01.2012
comment
Спасибо за ответ. Есть ли способ (через XMLSerializers / что-то еще?) Ускорить открытие канала? Почему этого не происходит в JAVA? - person chi-hawk; 23.01.2012
comment
Первое, что приходит в голову, - это провести профилирование, чтобы увидеть, где находится узкое место. В зависимости от того, какой инструмент профилирования вы используете, вам может потребоваться включить параметр для просмотра методов .NET framework. Кроме того, вы можете попытаться открыть канал и оставить его открытым до того, как пользователю действительно понадобится сделать этот звонок. - person RQDQ; 23.01.2012