2

PubMed (医学雑誌) の記事データを含む XML ファイルをダウンロードする必要がある VB.Net で書かれた winform アプリケーションがあります。ストリーミングする必要があるため、一度に 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

これをマルチスレッド化するための賢明なアプローチと思われる 1 つのアイデアは、「ネットワーク読み取り」を「ディスク書き込み」から分離することです。ディスク書き込みをマルチスレッド化してもパフォーマンスは向上しない可能性がありますが (高速ネットワーク ストレージでは例外の可能性があります)、ネットワーク リクエストは向上する可能性があります。したがって、ブロック全体をマルチスレッド化する代わりに、次のようにします。

  • Queue着信XmlDocumentオブジェクト用の を作成する
  • 1 つ (または複数) のスレッドを実行してサービス要求を処理しQueue、応答が到着したときにオブジェクトを にプッシュします。
  • 個別のスレッドを実行して監視し、Queue各項目をディスクに書き込みます

このようにして、どちら側がボトルネックであっても、プロセス全体が最適な速度に近づきます。次に、 の片側または両側で複数のスレッドを試して、Queue並列リクエスト/並列ディスク IO が役立つかどうかを確認できます。

へのスレッドセーフなアクセスを確保する必要があることを覚えておく価値がありますがQueue、それはかなり簡単に解決できます (.NET で最も簡単な方法は、Queue.Synchronizedメソッドを使用して既存の へのスレッドセーフなアクセスを取得することですQueue)。

于 2013-04-10T19:22:05.380 に答える