非同期ファイルのダウンロードにHttpClientを使用する

デビッドロジャース

csvファイルをPOSTリクエストに返すサービスがあります。非同期の手法を使用して、上記のファイルをダウンロードしたいと思います。ファイルを取得することはできますが、コードにはいくつかの未解決の問題と質問があります。

1)これは本当に非同期ですか?

2)チャンク形式で送信されている場合でも、コンテンツの長さを知る方法はありますか?プログレスバーを考えてください)。

3)すべての作業が完了するまでプログラムの終了を延期するために、どうすれば進行状況を最適に監視できますか。

using System;
using System.IO;
using System.Net.Http;

namespace TestHttpClient2
{
    class Program
    {
        /*
         * Use Yahoo portal to access quotes for stocks - perform asynchronous operations.
         */

        static string baseUrl = "http://real-chart.finance.yahoo.com/";
        static string requestUrlFormat = "/table.csv?s={0}&d=0&e=9&f=2015&g=d&a=4&b=5&c=2000&ignore=.csv";

        static void Main(string[] args)
        {
            while (true) 
            {
                Console.Write("Enter a symbol to research or [ENTER] to exit: ");
                string symbol = Console.ReadLine();
                if (string.IsNullOrEmpty(symbol))
                    break;
                DownloadDataForStockAsync(symbol);
            }
        }

        static async void DownloadDataForStockAsync(string symbol)
        {
            try
            {
                using (var client = new HttpClient())
                {
                    client.BaseAddress = new Uri(baseUrl);
                    client.Timeout = TimeSpan.FromMinutes(5);
                    string requestUrl = string.Format(requestUrlFormat, symbol);

                    //var content = new KeyValuePair<string, string>[] {
                    //    };
                    //var formUrlEncodedContent = new FormUrlEncodedContent(content);

                    var request = new HttpRequestMessage(HttpMethod.Post, requestUrl);
                    var sendTask = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
                    var response = sendTask.Result.EnsureSuccessStatusCode();
                    var httpStream = await response.Content.ReadAsStreamAsync();

                    string OutputDirectory = "StockQuotes";

                    if (!Directory.Exists(OutputDirectory))
                    {
                        Directory.CreateDirectory(OutputDirectory);
                    }

                    DateTime currentDateTime = DateTime.Now;
                    var filePath = Path.Combine(OutputDirectory, string.Format("{1:D4}_{2:D2}_{3:D2}_{4:D2}_{5:D2}_{6:D2}_{7:D3}_{0}.csv",
                        symbol,
                        currentDateTime.Year, currentDateTime.Month, currentDateTime.Day,
                        currentDateTime.Hour, currentDateTime.Minute, currentDateTime.Second, currentDateTime.Millisecond
                        ));

                    using (var fileStream = File.Create(filePath))
                    using (var reader = new StreamReader(httpStream))
                    {
                        httpStream.CopyTo(fileStream);
                        fileStream.Flush();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error, try again!");
            }
        }

    }
}
ピーター・ドゥニホ
  1. 「これは本当に非同期ですか?」

はい、ほとんどです。このDownloadDataForStockAsync()メソッドは、操作が完了する前にawait response.Content.ReadAsStreamAsync()ステートメントで返されます。

主な例外は、メソッドの終わり近くで、を呼び出しますStream.CopyTo()これは非同期ではなく、操作が長くなる可能性があるため、顕著な遅延が発生する可能性があります。ただし、コンソールプログラムでは、メソッドの継続は元の呼び出しスレッドではなくスレッドプールで実行されるため、気付かないでしょう。

このコードをWinformsやWPFなどのGUIフレームワークに移動する場合は、ステートメントを次のように変更する必要があります。 await httpStream.CopyToAsync(fileStream);

  1. チャンク形式で送信されている場合でも、コンテンツの長さを知る方法はありますか?プログレスバーを考えてください)。

サーバーがContent-Lengthヘッダーにを含むと仮定すると(そしてそうすべきです)、はい。これは可能であるはずです。

を使用している場合HttpWebRequest、応答オブジェクトにはContentLengthこの値を直接与えるプロパティがあることに注意してくださいHttpRequestMessage代わりにここを使用してますが、私はあまり詳しくありません。しかし、私が知る限り、次のContent-Lengthような値にアクセスできるはずです

long? contentLength = response.Content.Headers.ContentLength;

if (contentLength != null)
{
    // use value to initialize "determinate" progress indication
}
else
{
    // no content-length provided; will need to display progress as "indeterminate"
}
  1. すべての作業が完了するまでプログラムの終了を延期するために、どうすれば進行状況を最もよく監視できますか。

方法はたくさんあります。私は、任意の合理的な方法は、あなたが変更することを必要とすることを指摘しますDownloadDataForStockAsync()、それは返すようにメソッドをTaskしていませんvoidそうしないと、作成されたタスクにアクセスできません。とにかくこれを行う必要があるので、それは大したことではありません。:)

最も簡単なのは、開始するすべてのタスクのリストを保持し、それらを待ってから終了することです。

static void Main(string[] args)
{
    List<Task> tasks = new List<Task>();

    while (true) 
    {
        Console.Write("Enter a symbol to research or [ENTER] to exit: ");
        string symbol = Console.ReadLine();
        if (string.IsNullOrEmpty(symbol))
            break;
        tasks.Add(DownloadDataForStockAsync(symbol));
    }

    Task.WaitAll(tasks);
}

もちろん、これには、Taskすでに完了しているオブジェクトを含め、各オブジェクトのリストを明示的に維持する必要がありますこれを長時間実行して非常に多くのシンボルを処理する場合は、法外なことになる可能性があります。その場合、CountDownEventオブジェクトを使用することをお勧めします。

static void Main(string[] args)
{
    CountDownEvent countDown = new CountDownEvent();

    while (true) 
    {
        Console.Write("Enter a symbol to research or [ENTER] to exit: ");
        string symbol = Console.ReadLine();
        if (string.IsNullOrEmpty(symbol))
            break;

        countDown.AddCount();
        DownloadDataForStockAsync(symbol).ContinueWith(task => countdown.Signal()) ;
    }

    countDown.Wait();
}

これは、CountDownEvent作成するタスクごとにカウンターをインクリメントし、各タスクに継続をアタッチしてカウンターをデクリメントするだけです。カウンタがゼロに達すると、イベントが設定され、呼び出しWait()を返すことができます。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

ファイルを非同期でダウンロードする

分類Dev

多くのファイルを非同期でダウンロードする

分類Dev

C#でTPLを使用して非同期ファイルのダウンロードを実現する方法

分類Dev

Powershellを使用して複数の大きなファイルを非同期でダウンロードする

分類Dev

Javaで複数のファイルを並列または非同期にダウンロードする

分類Dev

httpClientと同期してファイルをダウンロードする

分類Dev

複数のファイルをダウンロードする非同期VB.net

分類Dev

Python 2.7を使用してマルチスレッド(非同期ダウンロード)でHTTP経由でファイルをダウンロードする方法

分類Dev

SSH.Net非同期ファイルのダウンロード

分類Dev

HttpClientでダウンロードしたファイルを特定のフォルダーに保存する方法

分類Dev

iOSで特定の順序でファイルを非同期にダウンロードするにはどうすればよいですか?

分類Dev

webClient C#を使用した非同期ファイルダウンロードでDownloadFileCompletedにファイル名を渡す

分類Dev

非同期ファイルのアップロードは、ブラウザにファイルのダウンロードを要求しません

分類Dev

リクエストにより非同期でファイルを効率的にダウンロード

分類Dev

内容を確認するよりもファイルをダウンロードしてuntarし、非同期待機の問題、node.js

分類Dev

joomlaテンプレートファイルでjsファイルを非同期にロードする方法

分類Dev

Angular:HttpClientからファイルをダウンロードする方法は?

分類Dev

httpClientとAngularを使用して.tarファイルをダウンロードする

分類Dev

画像を非同期で順番にダウンロードする

分類Dev

ファイルリーダーがファイルを非同期的にロードした後にファイル名を取得する

分類Dev

Almofireでビデオファイルの同期ダウンロードを再生することは可能ですか?

分類Dev

AzureVMにファイルをダウンロードする

分類Dev

wgetを使用して最新のファイルをダウンロードする

分類Dev

Pythonを使用して大量のファイルをダウンロードする

分類Dev

Googleドライブからローカルのダウンロードファイルにファイルをダウンロードする方法

分類Dev

javascriptファイルを非同期でロードする

分類Dev

現在のhtmlファイルをダウンロードする

分類Dev

Laravelがファイルを非同期にアップロードする

分類Dev

非同期HTTPクライアントを使用するAndroidマルチファイルをサーバーにアップロードする方法varphp?

Related 関連記事

  1. 1

    ファイルを非同期でダウンロードする

  2. 2

    多くのファイルを非同期でダウンロードする

  3. 3

    C#でTPLを使用して非同期ファイルのダウンロードを実現する方法

  4. 4

    Powershellを使用して複数の大きなファイルを非同期でダウンロードする

  5. 5

    Javaで複数のファイルを並列または非同期にダウンロードする

  6. 6

    httpClientと同期してファイルをダウンロードする

  7. 7

    複数のファイルをダウンロードする非同期VB.net

  8. 8

    Python 2.7を使用してマルチスレッド(非同期ダウンロード)でHTTP経由でファイルをダウンロードする方法

  9. 9

    SSH.Net非同期ファイルのダウンロード

  10. 10

    HttpClientでダウンロードしたファイルを特定のフォルダーに保存する方法

  11. 11

    iOSで特定の順序でファイルを非同期にダウンロードするにはどうすればよいですか?

  12. 12

    webClient C#を使用した非同期ファイルダウンロードでDownloadFileCompletedにファイル名を渡す

  13. 13

    非同期ファイルのアップロードは、ブラウザにファイルのダウンロードを要求しません

  14. 14

    リクエストにより非同期でファイルを効率的にダウンロード

  15. 15

    内容を確認するよりもファイルをダウンロードしてuntarし、非同期待機の問題、node.js

  16. 16

    joomlaテンプレートファイルでjsファイルを非同期にロードする方法

  17. 17

    Angular:HttpClientからファイルをダウンロードする方法は?

  18. 18

    httpClientとAngularを使用して.tarファイルをダウンロードする

  19. 19

    画像を非同期で順番にダウンロードする

  20. 20

    ファイルリーダーがファイルを非同期的にロードした後にファイル名を取得する

  21. 21

    Almofireでビデオファイルの同期ダウンロードを再生することは可能ですか?

  22. 22

    AzureVMにファイルをダウンロードする

  23. 23

    wgetを使用して最新のファイルをダウンロードする

  24. 24

    Pythonを使用して大量のファイルをダウンロードする

  25. 25

    Googleドライブからローカルのダウンロードファイルにファイルをダウンロードする方法

  26. 26

    javascriptファイルを非同期でロードする

  27. 27

    現在のhtmlファイルをダウンロードする

  28. 28

    Laravelがファイルを非同期にアップロードする

  29. 29

    非同期HTTPクライアントを使用するAndroidマルチファイルをサーバーにアップロードする方法varphp?

ホットタグ

アーカイブ