2016-12-25 9 views
3

私はWindowsコンソールクライアントを数分間スリープ状態にし、スリープ状態になると、Rest APIから新しい更新を要求します。リクエストはJSONデータで応答を生成します。オブジェクトのリストが含まれ、各オブジェクトはAPIからクライアントにURLとして送信されるID、description、screenshotで構成されます。コンソールアプリケーションはjsonレスポンスを消費する必要があり、オブジェクトごとにURLをルックアップし、リスト内の各オブジェクトに関連付けられた対応するイメージをダウンロードしようとします。コードが発現されるC#でTPLを使って非同期ファイルをダウンロードする方法

foreach (var jobject in response) 
{ 
    Console.WriteLine(jobject.id); 
    Console.WriteLine(jobject.description); 
    if (jobject.shotUrl != null) 
    { 
     WebClient webclient = new WebClient(); 
     webclient.DownloadFileAsync(new System.Uri(jobject.shotUrl), "F:\\" + jobject.id + ".jpg"); 
    } 
} 

を次のように時々500写真のダウンロードを意味し、約500のJSONオブジェクトが存在することができます...再び500 webclientsを作成することを意味します。私はこれが良い考えではないと感じます。

私の質問は、私がTPLに頼っているとパフォーマンスを上げることができますか?どうすればいい?

System.Net.Http.HttpClient _client = new System.Net.Http.HttpClient(); 

をそして、あなたは、ファイルをダウンロードし、そのようなディスクに保存します方法書くことができます:HttpClientをを使用して

+3

あなた自身の意見は矛盾しています。あなたはより多くのパフォーマンス*を望んでいるのですか? – zaitsman

+0

エンドポイントごとにデフォルトの接続制限がありますが、コンソールアプリケーションでは2 IIRCです。つまり、2つ以上同時にダウンロードすることはできません。以下を参照してください:https://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit(v=vs.110).aspx – rene

+2

この質問の@reneには、同時接続を増やす方法が示されていますhttp://stackoverflow.com/questions/26206412/asynchronous-downloading-files-in-c-sharp – Alrehamy

答えて

1

は、同時実行のためにはるかに簡単です、あなたはクラスに1プライベートのHttpClientを宣言することができ

private async Task DownloadFile(string shortUrl, string destination) 
{ 
    using (var response = await _client.GetStreamAsync(shortUrl)) 
    using (var fileStream = File.Create(destination)) 
    { 
     await response.CopyToAsync(fileStream); 
     await fileStream.FlushAsync(); 
    } 
} 

その後、あなたはこのようにそれを使用することができます:

try 
{ 
    await DownloadFile(jobject.shortUrl, "F:\\" + jobject.id + ".jpg"); 
} 
catch (Exception e) 
{ 
    // Do appropriate exception handling 
} 

そして、あなたがワン場合すべてのファイルを並行してダウンロードするには、Task.WhenAll()を使用することができます。

try 
{ 
    var tasks = response.Select(j => DownloadFile(j.shortUrl, "F:\\" + j.id + ".jpg")); 
    await Task.WhenAll(tasks); 
} 
catch (Exception e) 
{ 
    // Do appropriate exception handling 
} 
+1

私はあなたのコードをベンチマークしました。そのパフォーマンスは私のオリジナルの仕事より悪いです – Alrehamy

+0

正直言って、私は十分なコンテキストを持っていなかったので、コードを一切実行しませんでした。しかし、私は非同期コードを微調整することで(特にTask.WhenAll)より良いパフォーマンスを提供することができます。 – Encrypt0r

+0

並行してファイルをダウンロードする場合は、 'async'で実行する必要があります。' async j => await DownloadFile'は、 'j => DownloadFile'だけでなく、並行して同期的に行われるためです。 – VMAtm

関連する問題