質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

2385閲覧

C#async awaitで2以上の同時処理の結果を受けたかどうやって判断するのでしょうか?

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2017/07/12 09:58

編集2017/07/12 10:13

C#の非同期処理で、async awaitを使うと処理が終わるまでawaitで待って結果を受け取ります。
WebClinentで情報を取得して結果を待って返します。

C#

1public async Task<string> ReadFromUrlAsync(Uri url) { 2 using (WebClient webClient = new WebClient()) { 3 using (Stream stream = await webClient.OpenReadTaskAsync(url)) { 4 TextReader tr = new StreamReader(stream, Encoding.UTF8, true); 5 return await tr.ReadToEndAsync(); 6 } 7 } 8} 9 10public async Task DownloadAsync() { 11 Uri url = new Uri("http://www.sample-abc.com"); 12 string body = await ReadFromUrlAsync(url); 13 Console.WriteLine(body); 14}

しかし、2つ以上のURLに同時にアクセスして、全ての結果を受け取るまで待機っていうのはどのようにするのでしょうか?
もし以下のようにしたら非同期だけど最初のurlのbodyを取得してから次のurlを取得しに行くので同期処理になります。

C#

1public async Task DownloadAsync() { 2 Uri url1 = new Uri("http://www.sample-abc.com"); 3 string body1 = await ReadFromUrlAsync(url1); 4 Console.WriteLine(body1); 5 6 Uri url2 = new Uri("http://www.sample-xyz.com"); 7 string body2 = await ReadFromUrlAsync(url2); 8 Console.WriteLine(body2); 9 10 // awaitで待っているので処理終了をここで出力 11 Console.WriteLine("処理終了"); 12}

求めているのは2つ以上の同時アクセスなのでawaitで待たずに次のurl取得処理に移行させるためにasync Task<string>ではなくasync voidにすればいいのでしょうが、上記2つのurlに同時アクセスしてどちらもbody取得を完了したかをどのように判断して最後のConsole.WriteLine("処理終了");を出力するにはどのようにすれば良いのでしょうか?

開発環境:Windows10 + VisualStudio2015 C# .NetFrameWork4.6.x

どうぞ宜しくお願いします。

対応アプリケーションの種類はWinFormです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Task.WaitAllを使う。 https://msdn.microsoft.com/ja-jp/library/dd270695(v=vs.110).aspx
こういう拡張メソッドを使うと便利らしい。 http://engineering.grani.jp/entry/2017/04/06/163904
(環境を見たら2015なので、使えませんね)

あと、WebClientではなくて、HttpClientを使うといいのでは。

通信の返り値に、Stringを使いたいのはよく分かるけど、通信は失敗することがあるので、返り値がNullにすると、失敗の理由がわからないので、一応、あまりよくない。

投稿2017/07/12 10:07

編集2017/07/12 10:19
kiichi54321

総合スコア1984

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/07/12 10:21

ありがとうございます! >http://engineering.grani.jp/entry/2017/04/06/163904 これは便利そうですね! ちょっと使ってみようと思います! >あと、WebClientではなくて、HttpClientを使うといいのでは。 というのはなぜでしょうか・・・?
kiichi54321

2017/07/12 10:30 編集

HttpClient は、Taskを使う前提で作られていて、今時のRESTに対応している。というか、ReadFromUrlAsyncは、わざわざ作らなくても、HttpClientに同等のがある。同期的に、URLを叩くくらいなら、WebClientを使いますけど、それ以上のことをするとなると、HttpClientのほうがいいです。WebClientは古いってことですね。
退会済みユーザー

退会済みユーザー

2017/07/12 10:40

ありがとうございます! HttpClientについては別途調べて使ってみます。 あとTask.WaitAllも使ってみますね。 リンクのほうは2017だったのですね・・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問