1var dataRows = await InputData.GetRowsAsync();// データ取得Task<List<InputData.Row>>(並列したい)2var mstRows = await Master.GetRowsAsync();// マスタ取得Task<List<Master.Row>>(並列したい)34// 二つを組み合わせる5var query = from d in dataRows
6 join m in mstRows
7 on r.parts_name equals m.parts_name into mJoin
8 from mj in mJoin.DefaultIfEmpty()9 Select new {...}1011// ↓↓↓queryを使った処理↓↓↓
試したこと
TaskをWhenAllし、Resultを利用することを考えました。
C#
1var dataRows = InputData.GetRowsAsync();// データ取得Task<List<InputData.Row>>2var mstRows = Master.GetRowsAsync();// マスタ取得Task<List<Master.Row>>34// 並列して実行するタスクを待機する5await Task.WhenAll(dataRows, mstRows);67// 二つを組み合わせる8var query = from d in dataRows.Result
9 join m in mstRows.Result
10 on r.parts_name equals m.parts_name into mJoin
11 from mj in mJoin.DefaultIfEmpty()12 Select new {...}1314// ↓↓↓queryを使った処理↓↓↓
そもそもの話として、相手が DB で Linq to Entities で処理するなら、Linq 式で JOIN した SELECT クエリが生成され、それを一本だけ DB に投げて目的のデータを取得できるのではないですか? であれば、クエリを 2 つに分けるより、その方が早いのではないですか?
回答1件
0
ベストアンサー
これらの取得を並列Taskで実行して処理の高速化を目指します。
以下の記事の「マルチスレッドの動作原理」セクションにある図の ② のようになると、OS がスレッドを切り替えて処理を行うのでそのオーバーヘッドの分逆に遅くなるということになりますので、③ のようにマルチコアを利用できる環境が必要で、さらにマルチコアを利用できるプログラミングを行うという話になると思います。
Task.WhenAll(work0, work1); に await を付与すればデッドロックにはならないこと確認できました。後で質問欄を修正しておきます。ご指摘ありがとうございました。
Microsoft のドキュメントのタスク並列ライブラリ (TPL) の説明には "The TPL scales the degree of concurrency dynamically to most efficiently use all the processors that are available." とありますが、await Task.WhenAll(...) ではそのあたりは OS 任せになるということでしょうか。
TPL を使った場合 UI がブロックされるのは避けられないようですし、非同期バージョンのメソッドしかない場合は TPL ではどうしようもなさそうですし、await Task.WhenAll(...) を使って後は OS に良しなにやってもらうということにするべきなのかもしれませんね。