【问题标题】:Slow first call to C# web service缓慢第一次调用 C# Web 服务
【发布时间】:2012-02-17 00:02:08
【问题描述】:

我正在尝试访问此处提供的 PubMed 网络服务:

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

我用 Java 编写了访问 Web 服务的代码,返回时间不到 1 秒。我用 C# 编写代码来访问相同的 Web 服务,初始调用的返回时间大约为 12 秒,然后所有后续调用的返回时间不到 1 秒。

我尝试以两种方式在 C# 中写入 Web 服务 - 都作为控制台应用程序。首先是标准的“右键单击引用并执行“添加服务引用””,它将向 app.config 添加信息,您可以使调用变得轻松而轻松。第二个是使用 wsdl.exe 创建一个 dll 并尽可能“直接”访问 Web 服务(无向导)。两种方式都提供相同的结果。我将发布两个各自的代码片段。

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 页面进行这些 Web 服务调用,因此第一次调用的 12 秒返回时间是不可接受的。

我考虑将其发布在 BioStar 上,但它的参与度不如这个论坛。如果这里没有找到答案,我可能会这样做。

有什么想法吗?

【问题讨论】:

  • 您的 WCF 服务是如何托管的?如果您在 IIS 中托管,那么第一次调用有可能必须启动整个 WCF 运行时基础结构(ServiceHost 等等)。这将比任何后续调用都更昂贵...
  • @marc_s 这一切都是在我的控制台应用程序中完成的。我还没有在 ASP.NET 页面上运行它

标签: c# web-services serialization pubmed


【解决方案1】:

第一次调用打开通道(相对昂贵),第二次调用利用已经打开的通道(更便宜)。

【讨论】:

  • 感谢您的回复。有什么方法(通过 XMLSerializers/其他东西?)来加快通道的打开速度?为什么在 JAVA 中不是这样?
  • 首先想到的是做一些分析,看看瓶颈在哪里。根据您使用的分析工具,您可能需要打开一个选项才能查看 .NET 框架方法。除此之外,您还可以尝试在用户实际需要拨打电话之前打开一个频道并使其保持打开状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 2018-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-22
相关资源
最近更新 更多