12974


C# AsyncでWEB画像を複数枚ダウンロードする時の非同期の書き方ってこちらで合っていますか？  
for文がどうも変だと思うのですが。

[code]

    private async void DownloadImage(string []uri, string path)
    {
        HttpClient httpClient = new HttpClient();
    
        for (int i = 0; i < uri.Length; i++)
        {
            HttpResponseMessage res = await httpClient.GetAsync(uri[i], HttpCompletionOption.ResponseHeadersRead);
    
            using (var fileStream = File.Create(path+(i+1)+".jpg"))
            {
                using (var httpStream = await res.Content.ReadAsStreamAsync())
                {
                    httpStream.CopyTo(fileStream);
                    fileStream.Flush();
                }
            }
        }
     }
    
[/code]


CC BY-SA 3.0
2015-08-03T03:47:55.417
12967
2017-06-19T02:37:05.567
2017-06-19T02:37:05.567
19110
7973
question
c# 非同期
C# AsyncでWEB画像を複数枚ダウンロード


`await`の時点でその操作の完了を待ってしまいます。  
並列にダウンロードしたい場合は、１つ１つのダウンロードを行う`Task`を用意しそれを`Task.WhenAll()`で待つ必要があります。

[code]

    static async Task DownloadImage(HttpClient httpClient, string uri, string path) {
        using (var res = await httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead))
        using (var fileStream = File.Create(path))
        using (var httpStream = await res.Content.ReadAsStreamAsync())
            await httpStream.CopyToAsync(fileStream);
    }
    
    static async Task DownloadImage(string[] uris, string path) {
        using (var httpClient = new HttpClient())
            await Task.WhenAll(uris.Select((uri, i) => DownloadImage(httpClient, uri, string.Format("{0}{1}.jpg", path, i + 1))));
    }
    
[/code]

こまごまと指摘があります。

  * 全てのダウンロードの完了を知るためにも戻り値は`Task`の方がいいでしょう。
  * `ReadAsStreamAsync()`は読み取り開始でしかなくダウンロード全体に関しては`CopyTo()`部分も`CopyToAsync()`にすべきです。
  * `IDisposable`に関しては`using`などで全て`Dispose()`しておくべきです。
  * `FileStream`は`using`してあれば`Fluash()`不要です。
  * `using`をネストする際、括弧を書かなければインデントが深くなりません。


CC BY-SA 3.0
2015-08-03T05:23:39.573
12974
2015-08-03T05:23:39.573
4236
12967
answer