BeginRead
非同期プログラミング モデル (APM) のイディオム (例: / )を使用して C# で記述した高性能ファイル転送コードがありますEndRead
。このコードは、ローカル ディスクからファイルを読み取り、それをソケットに書き込みます。
最新のハードウェアで最高のパフォーマンスを得るには、可能な限り、複数の未処理の I/O 操作を実行しておくことが重要です。したがって、ファイルにいくつかの操作を投稿し、1 つが完了するとソケットでBeginRead
a を呼び出し、それが完了するとファイルで別の操作を行います。詳細はそれよりも少し複雑ですが、大まかに言えばそれがアイデアです。BeginSend
BeginRead
私は APM ベースのコードを動作させましたが、理解するのが非常に難しく、おそらく同時実行の微妙なバグがあります。代わりに TPL を使用したいと思います。Task.Factory.FromAsync
すぐにやろうと思ったのですが、落とし穴があります。
私が見たすべての I/O サンプル (特にStreamExtensions
Parallel Extensions Extras のクラス) は、1 回の読み取りと 1 回の書き込みが続くことを前提としています。これは私が必要とする方法を実行しません。
非同期 I/O タスクはワーカー スレッドに多くの時間を費やさないためParallel.ForEach
、Extras 拡張などの単純なものは使用できません。そのため、Parallel は別のタスクを開始するだけで、数十または数百の保留中の I/O 操作が発生する可能性があります。 Task.Factory.Iterate
; やりすぎ!タスクを ing することでこれを回避できWait
ますが、イベント ハンドル (カーネル オブジェクト) が作成され、ワーカー スレッドを拘束するタスク待機ハンドルで待機がブロックされます。私の APM ベースの実装では、これらの両方を回避しています。
複数の読み取り/書き込み操作を実行中のままにしておくためのさまざまな方法をいじっており、別のタスクを作成するメソッドを呼び出す継続を使用してそれを行うことができましたが、ぎこちなく感じ、間違いなくそうではありません慣用的な TPL。
TPL でこのような問題に取り組んだ人は他にいますか? 助言がありますか?