みなさん、並列処理、書いてますか? つらい、つらいよね、わかるよ。
ある部分は高速化のために並列で実行し、ある部分は整合性を取るために直列で実行し、入力ジョブのキューが膨大にならないように流量を調節しながらジョブを入力して……。こんなプログラムをバグなく書くなんて、それはもう大変で、コーナーケースからぼろが出てくる出てくるって感じになります。
さて、そんな面倒な並列プログラミングを支えてくれるライブラリが、結構前(2014 年の NuGet パッケージが存在している。概念自体は 2011 年からある?)から提供されています。名前だけはご存知(個人的な感想) System.Threading.Tasks.Dataflow、通称 TPL Dataflow です。 .NET Core では標準で含まれていますし、そうでない環境では NuGet からダウンロードできます。強いですね。
公式ドキュメントも比較的しっかり書かれています。日本語翻訳がまともかというと何とも言えないですが、翻訳が崩壊しているページよりはまともです。
今まで、イマイチ使いどころがわからない & 複雑で学習コストが高そうだと感じ、避けてきたのですが、触ってみたらかなり便利ということがわかったので、各種オプションによってどのような挙動をするのかをまとめて、今後使うときのメモとしておこうというのが、この記事の目的です。前半では、この目的通り、使い方を説明します。後半では、同じく TPL(Task Parallel Library) という枠で提供されている Parallel クラスや、似たような概念を提供する Reactive Extensions、System.Threading.Channels との比較を行います。
環境は、 .NET Core 2.2 を想定しています。 System.Threading.Tasks.Dataflow の古いバージョンでは、存在しない機能があるかもしれません。
- TPL Dataflow の使い方
- インターフェイスの紹介
- 最初の例: 入力データに対して処理を直列に行う
- データを変換する TransformBlock とリンク
- 完了、キャンセル、例外の伝搬
- ブロック中の SynchronizationContext
- 並列化
- 出力データの順番
- バッファー上限と SendAsync
- 複数のブロックに同じデータを送信する
- 入力データをまとめて配列にする BatchBlock
- 最短一致モード、最長一致モード
- ちょっと大規模なサンプル: マネージドキューサービスからジョブを取り出し、実行するワーカー
- 経緯
- マネージドキューサービスのモデル
- データフローブロックを組んでいく
- 完成形
- 類似品との比較
- Parallel, PLINQ
- Reactive Extensions
- System.Threading.Channels
- まとめ
続きを読む