3

私は、多くの (数百、場合によっては数千) の並列プロセスを持つことになっている、ネットワークにバインドされたアプリケーションに取り組んでいます。

私はそれを実装するための最良の方法を探しています。

設定してみたところ

ThreadPool.SetMaxThreads(int.MaxValue, int.MaxValue);

1000 個のスレッドを作成してそれらを並列処理するよりも、アプリケーションの実行が非常に不安定になりました。

delegate.BeginInvokeどこかでそれよりも優れていると聞いたnew Thread(...)ので、試してみましたが、デバッガーでアプリを開いたところ、並列スレッドが表示されました。

大量のスレッドを作成する必要がある場合、アプリケーションがスムーズに実行されるようにするための最善の方法は何ですか?

4

3 に答える 3

8

await / asyncC# 5 / .NET 4.5 で新しいパターンを試しましたか?

これが内部でどのように動作するかについての情報源はありませんが、この新機能の最も一般的な使用例の 1 つは、IO バウンドのものを待機することです。


スレッドは軽量オブジェクトではありません。それらは作成するのに費用がかかり、コンテキストの切り替えが必要です。したがって、スレッドプールの理由 (事前に作成され、再利用されます)。ネットワークやその他の IO ポートを含む最も一般的なソリューションでは、低レベルの IO Completion Ports (マネージ ライブラリがここにあります) を使用してポートを "待機" しますが、スレッドは通常どおり実行を継続できます。

BeginInvokeはスレッド プール スレッドを利用するため、スレッドが利用可能な場合にのみ独自に作成するよりも優れています。このアプローチを頻繁に使用すると、すぐにスレッドの枯渇につながる可能性があります。

このように高いスレッド プール カウントを設定しても、長期的には機能しません。実行したい処理に対してスレッドが重すぎるためです。


Axum は、以前は Microsoft Research の言語であり、このタスクに適した大規模な並列処理を実現するために使用されていました。Stackless Python や Erlang と同様に動作します。Axum の多くの概念が、C# 5 と .NET 4.5 への並列処理への道を歩み始めました。

于 2012-11-16T16:25:40.273 に答える
2

ThreadPool.SetMaxThreadsの設定は、スレッドプールにあるスレッドの数にのみ影響し、新しいThread()を使用して自分で作成したスレッドに関しては違いはありません。

多くの人が提案しているように、非同期(キーワードではなくモデル)に移行します。

于 2012-11-16T16:48:53.253 に答える
0

他の回答やコメントに記載されているアドバイスに従う必要があります。fsimonazzi が言うように、新しいスレッドを直接作成することは、ThreadPool とは何の関係もありません。簡単なテストを行うには、最大ワーカー スレッドと completionPort スレッドを減らし、ThreadPool.QueueUserWorkItemメソッドを使用します。ThreadPool は、システムが処理できるものを決定し、タスクをキューに入れ、可能な限りスレッドを再利用します。

タスクがコンピューティング バウンドでない場合は、非同期 I/O も利用する必要があります。ワーカー スレッドが I/O の完了を待つ必要はありません。これらのワーカー スレッドができるだけ早くプールに戻り、I/O 要求でブロックされないようにする必要があります。

于 2012-11-16T17:55:04.820 に答える