こんにちは。エクセルソフトの田淵です。
勉強がてら、複数のサイトから Json を引っ張ってきて ListView に表示するだけのアプリを作っているのですが、以下のようなイメージで await, await, await してたら当然遅いわけです。
(Xamarin は勉強や調査で C# のコンソールアプリや WPF でかなりお手軽に試せるので初心者には嬉しいですね。)
private async void button1_Click(object sender, RoutedEventArgs e) { var sw = new Stopwatch(); sw.Reset(); sw.Start(); string str1 = await SomeTaskAsync1("foo"); string str2 = await SomeTaskAsync("bar"); string str3 = await SomeTaskAsync("baz"); sw.Stop(); label.Content = string.Format("sw.Elapsed: {0:ss}.{0:ff} sec\n{1}\n{2}\n{3}", sw.Elapsed, str1, str2, str3); }
直接 Async メソッドを await するのではなく、Task<TResult> にしてから (2015/7/20 追記) Task.WhenAll(Task) で同時に実行すると並列処理が出来るようです。Task は難しくて全然分かりません。。
渋木さん、平野さん、コメントありがとうございます。
参考:方法: Task.WhenAll を使用してチュートリアルを拡張する (C# および Visual Basic)
await すると自動で並列処理してくれるようなので忘れないようにメモしておきます。
private async void button2_Click(object sender, RoutedEventArgs e) { var sw = new Stopwatch(); sw.Reset(); sw.Start(); // 多分こうやる。 (2015/7/20 追記) Task<string> task1 = SomeTaskAsync("foo"); Task<string> task2 = SomeTaskAsync("bar"); Task<string> task3 = SomeTaskAsync("baz"); IEnumerable<Task<string>> tasks = new[] { task1, task2, task3 }; // WhenAll するまで "task1 Id = 97, Status = WaitingForActivation, Method = "{null}", Result = "{未計算}" と出ているので多分遅延実行というやつなんだと思います。 string[] results = await Task.WhenAll(tasks); // これは良くないやり方 // var str1 = await task1; // var str2 = await task2; // var str3 = await task3; sw.Stop(); label.Content = string.Format("sw.Elapsed: {0:ss}.{0:ff} sec\n{1}\n{2}\n{3}", sw.Elapsed, results[0], results[1], results[2]); }
GW 中、Parallel.Invoke
とか Queue<T>
とか調べて悩んでたんですけどウチの技術に聞いたらすぐに 方法: Async と Await を使用して複数の Web 要求を並列実行する (C# および Visual Basic) を教えてくれました笑
助かりますな…
(ところで var str1 = await GetTaskAsync("task1");
と await すると var は TResult の string になって、await しないと var が Task
GetTaskAsync はサンプルとしてランダムに Delay するだけの単純なやつです。
public async Task<string> SomeTaskAsync(string arg) { var rnd = new Random(); var randomInt = rnd.Next(1, 10); await Task.Delay(randomInt * 100); return string.Format("{0}: {1}ms", arg, randomInt * 100); }
これで早くなるといいなー。
以上です。