5

BeginRead非同期プログラミング モデル (APM) のイディオム (例: / )を使用して C# で記述した高性能ファイル転送コードがありますEndRead。このコードは、ローカル ディスクからファイルを読み取り、それをソケットに書き込みます。

最新のハードウェアで最高のパフォーマンスを得るには、可能な限り、複数の未処理の I/O 操作を実行しておくことが重要です。したがって、ファイルにいくつかの操作を投稿し、1 つが完了するとソケットでBeginReada を呼び出し、それが完了するとファイルで別の操作を行います。詳細はそれよりも少し複雑ですが、大まかに言えばそれがアイデアです。BeginSendBeginRead

私は APM ベースのコードを動作させましたが、理解するのが非常に難しく、おそらく同時実行の微妙なバグがあります。代わりに TPL を使用したいと思います。Task.Factory.FromAsyncすぐにやろうと思ったのですが、落とし穴があります。

私が見たすべての I/O サンプル (特にStreamExtensionsParallel Extensions Extras のクラス) は、1 回の読み取りと 1 回の書き込みが続くことを前提としています。これは私が必要とする方法を実行しません。

非同期 I/O タスクはワーカー スレッドに多くの時間を費やさないためParallel.ForEach、Extras 拡張などの単純なものは使用できません。そのため、Parallel は別のタスクを開始するだけで、数十または数百の保留中の I/O 操作が発生する可能性があります。 Task.Factory.Iterate; やりすぎ!タスクを ing することでこれを回避できWaitますが、イベント ハンドル (カーネル オブジェクト) が作成され、ワー​​カー スレッドを拘束するタスク待機ハンドルで待機がブロックされます。私の APM ベースの実装では、これらの両方を回避しています。

複数の読み取り/書き込み操作を実行中のままにしておくためのさまざまな方法をいじっており、別のタスクを作成するメソッドを呼び出す継続を使用してそれを行うことができましたが、ぎこちなく感じ、間違いなくそうではありません慣用的な TPL。

TPL でこのような問題に取り組んだ人は他にいますか? 助言がありますか?

4

1 に答える 1

2

スレッドが多すぎることが心配な場合はParallelOptions.MaxDegreeOfParallelism、 への呼び出しで許容できる数に設定するだけParallel.ForEachです。

于 2010-05-13T12:11:36.053 に答える