2

我有一个用 VB.Net 编写的 winform 应用程序,它需要下载包含 PubMed(医学期刊)文章数据的 XML 文件。我一次请求 500 篇文章的数据,因为我需要对其进行流式传输,并且我想避免加载超出可用内存的文件。在返回的文件中,每篇文章的数据都包含在<PubmedArticle>元素中:

<PubmedArticleSet>
    <PubmedArticle>
    ... (Article Data) ...
    </PubmedArticle>
    <PubmedArticle>
    ... (Article Data) ...
    </PubmedArticle>
</PubmedArticleSet>

我的代码看起来像这样(实际代码在每次迭代 500 个 Pubmed ID 的循环中执行下面的代码):

Dim pubmedIDs As String() = {"20816578", "20815951"}
Dim xmlUrl As String = String.Format("{0}{1}{2}", "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id=", String.Join(",", pubmedIDs), "&retmode=xml&rettype=abstract")
Dim request as HttpWebRequest = DirectCast(WebRequest.Create(xmlUrl), HttpWebRequest)
Try
    Using response As WebResponse = request.GetResponse()
        Using responseStream As Stream = response.GetResponseStream()
            Dim xDoc As XDocument = XDocument.Load(responseStream)
            'Break up the requested file into one file per article and save them to a cache directory
            'Update a progress bar as files are cached
        End Using
    End Using
Catch ex As WebException
    'Handle HTTP errors by capturing Pubmed IDs of failed request to allow user to retry later
    'Update progress bar despite failed request to let user know when the process is finished
End Try

这一切都很好,但是在典型的运行中,我需要收集 20K+ 文件的文章数据,这大约需要 10 分钟。有人可以就如何对请求进行多线程处理给我建议吗?

4

1 回答 1

0

一个可能是多线程的明智方法的一个想法是将“网络读取”与“磁盘写入”分开。多线程磁盘写入可能不会带来性能优势(高速网络存储可能例外),但网络请求可能会受益。所以,不要多线程你的整个块,有这样的东西:

  • Queue为传入XmlDocument对象创建一个
  • Queue运行一个(或多个)线程来处理服务请求并在响应到达时将对象推送到
  • 运行一个单独的线程来监控Queue并将每个项目写入磁盘

这样,无论哪一方是瓶颈,整个过程都会运行到更接近最佳速度。然后,您可以在一侧或两侧试验多个线程,Queue看看并行请求/并行磁盘 IO 是否会有所帮助。

值得记住的是,您必须确保Queue对.Queue.SynchronizedQueue

于 2013-04-10T19:22:05.380 回答